Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ES6 classes && Object descriptor #15

Open
2zH opened this issue Apr 10, 2018 · 5 comments
Open

ES6 classes && Object descriptor #15

2zH opened this issue Apr 10, 2018 · 5 comments

Comments

@2zH
Copy link
Owner

2zH commented Apr 10, 2018

extends(inherits)

source code:

var inherits = function (subClass, superClass) {
    if (typeof superClass !== "function" && superClass !== null) {
      throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }

    subClass.prototype = Object.create(superClass && superClass.prototype, {
      constructor: {
        value: subClass,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
  };
  • superClass类型不为function或不为null,抛出一个类型错误
  • subClass的原型设定为通过Object.create函数创建的原型,参数为superClass.prototype
    constructor options,其中 constructor options 的 value 为 subClass
  • Object.setPrototypeOf函数存在,执行它,参数为subClasssuperClass,若不存在,直接把subClass__proto__指向superClass
@2zH
Copy link
Owner Author

2zH commented Apr 10, 2018

classCallCheck

example:

function foo(options) {
    classCallCheck(this, foo)
}

source code:

var classCallCheck = function (instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  };
  • 检查该示例的原型链中是否包含此构造函数的 prototype 属性

@2zH
Copy link
Owner Author

2zH commented Apr 10, 2018

possibleConstructorReturn

example:

inherits(foo, bar)
function foo(options) {
    classCallCheck(this, foo)
    var _this = possibleConstructorReturn(this, (foo.__proto__ || Object.getPrototypeOf(foo)).call(this, options));

}

source code:

var possibleConstructorReturn = function (self, call) {
    if (!self) {
      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
    }

    return call && (typeof call === "object" || typeof call === "function") ? call : self;
  };

@2zH
Copy link
Owner Author

2zH commented Apr 10, 2018

createClass

example:

function foo(options) {
    classCallCheck(this, foo)
}
createClass(foo, [{
    key: 'hello',
    value: function hello() {
        var _this2 = this
    }
}, {
    key: ...,
    value: ...
}])

source code:

var createClass = function () {
    function defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }

    return function (Constructor, protoProps, staticProps) {
      if (protoProps) defineProperties(Constructor.prototype, protoProps);
      if (staticProps) defineProperties(Constructor, staticProps);
      return Constructor;
    };
  }();

@2zH 2zH changed the title ES6 classes polyfill ES6 classes && Object descriptor Apr 10, 2018
@2zH
Copy link
Owner Author

2zH commented Apr 10, 2018

Object descriptor

在ES6中,由于 Symbol类型的特殊性,用Symbol类型的值来做对象的key与常规的定义或修改不同,而Object.defineProperty 是定义key为Symbol的属性的方法之一。

对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。

数据描述符和存取描述符均具有以下可选键值:

configurable
当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。若该属性被配置为false,则该属性不再可配置,并且没有属性可以被改变(除了单向改变 writable 为 false)。当属性不可配置时,不能在数据和访问器属性类型之间切换。
enumerable
当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。

数据描述符同时具有以下可选键值:

value
该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
writable
当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。

存取描述符同时具有以下可选键值:

get
一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。
set
一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。

如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(value或writable)和(get或set)关键字,将会产生一个异常。

引用:

  • MDN Object.defineProperty

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty/Additional_examples

@2zH
Copy link
Owner Author

2zH commented Apr 25, 2018

Reflect

Reflect是一个仅提供静态方法的全局对象,存在的目的是为了替代一些诸如 Function.prototype.apply() 这种调用方式,并且更为通用。从功能上来看与被替代的方法一致,只有返回的值或别的一些小细节上存在不同。

Reflect.constructor()
Reflect.apply()
Reflect.defineProperty()
Reflect.deleteProperty()
Reflect.get()
Reflect.getOwnPropertyDescriptor()
Reflect.getPrototypeOf()
Reflect.has()
Reflect.isExtensible()
Reflect.ownKeys()
Reflect.preventExtensions()
Reflect.set()
Reflect.setPrototypeOf()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant