理解Object.create

Object.create()方法是用来创建新的对象,并且可以指定原型(proto),和设定自身属性(propertiesObject)。如果指定的原型(proto)不是null或者一个对象值,将会抛出类型错误异常。

1
Object.create(proto[, propertiesObject])

在js里,所有的端口都默认继承至Obejct,如果使用此方法创建一个对象,需要指定原型为Object.prototype,如果传入null的话,就不继承任何东西。

1
2
3
4
5
6
7
// 这3种创建对象都是等价的
var a = new Obejct();
var b = {};
var c = Object.create(Object.prototype);
// d 不继承任何东西
var d = Object.create(null);

实现类式继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 超类
function Shape(x, y){
this.x = x;
this.y = y;
};
Shape.prototype.move = function(x, y){
this.x += x;
this.y += y;
console.log('Move');
};
// 子类
function Rectangle(x, y){
Shape.call(this, x, y); //调用超类的构造函数
};
Rectangle.prototype = Object.create(Shape.prototype);
var rect = new Rectangle(1, 1);
console.log(rect instanceof Rectangle); // true
console.log(rect instanceof Shape); // ture
rect.move(10, 2); // Move

设置对象属性

所有属性特性默认为false

  • writable 可写
  • configurable 可配置
  • enumerable 可枚举
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var obj = Object.create(Object.prototype, {
foo: {
writable: true,
configurable: true,
value: 10
},
baz: {
configurable: false,
get: function(){ return 'hello'},
set: function(val){console.log('set value ' + val)}
}
});
// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
var o = Object.create({}, { p: { value: 42 } })
// 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
o.p = 24
o.p
//42
o.q = 12
for (var prop in o) {
console.log(prop)
}
//"q"
delete o.p
//false

Polyfill

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
if (typeof Object.create != 'function') {
// Production steps of ECMA-262, Edition 5, 15.2.3.5
// Reference: http://es5.github.io/#x15.2.3.5
Object.create = (function() {
//为了节省内存,使用一个共享的构造器
function Temp() {}
// 使用 Object.prototype.hasOwnProperty 更安全的引用
var hasOwn = Object.prototype.hasOwnProperty;
return function (O) {
// 1. 如果 O 不是 Object 或 null,抛出一个 TypeError 异常。
if (typeof O != 'object') {
throw TypeError('Object prototype may only be an Object or null');
}
// 2. 使创建的一个新的对象为 obj ,就和通过
// new Object() 表达式创建一个新对象一样,
// Object是标准内置的构造器名
// 3. 设置 obj 的内部属性 [[Prototype]] 为 O。
Temp.prototype = O;
var obj = new Temp();
Temp.prototype = null; // 不要保持一个 O 的杂散引用(a stray reference)...
// 4. 如果存在参数 Properties ,而不是 undefined ,
// 那么就把参数的自身属性添加到 obj 上,就像调用
// 携带obj ,Properties两个参数的标准内置函数
// Object.defineProperties() 一样。
if (arguments.length > 1) {
// Object.defineProperties does ToObject on its first argument.
var Properties = Object(arguments[1]);
for (var prop in Properties) {
if (hasOwn.call(Properties, prop)) {
obj[prop] = Properties[prop];
}
}
}
// 5. 返回 obj
return obj;
};
})();
}

兼容性

  • es5 Initial definition. Implemented in JavaScript 1.8.5.
  • es6
浏览器:

pc端: ie9+
移动端: 安卓和iOS都支持

文献

developer.mozilla.org