javascript查漏补缺之二十 ——《继承和原型链》
/ / 点击 / 阅读耗时 5 分钟获取和设置原型对象的标准方法
- 获取:
Object.getPrototypeOf()
以后可以不用__proto__
这个属性了。
设置一个对象的属性
通常,设置一个对象的属性会创建这个对象自身的属性。但如果这个对象继承了getter
或setter
属性,就会出现例外。
比如下面这段代码:
1 | var o = { |
不同方式创建对象以及导致的原型链
使用字面两创建
var o = {a: 1};
, 原型链:o ---> Object.prototype ---> null
。var b = ['yo', 'whadup', '?'];
, 原型链:b ---> Array.prototype ---> Object.prototype ---> null
。function f() {return 2}
, 原型链:f ---> Function.prototype ---> Object.prototype ---> null
。
使用构造函数创建
1
2
3
4
5
6
7
8
9
10
11
12function Graph() {
this.vertices = [];
this.edges = [];
}
Graph.prototype = {
addVertex: function(v) {
this.vertices.push(v);
}
};
var g = new Graph();使用
Object.create
创建1
2
3
4
5
6
7
8
9
10
11
12
13
14var a = {a: 1};
// a ---> Object.prototype ---> null
var b = Object.create(a);
// b ---> a ---> Object.prototype ---> null
console.log(b.a); // 1 (inherited)
var c = Object.create(b);
// c ---> b ---> a ---> Object.prototype ---> null
var d = Object.create(null);
// d ---> null
console.log(d.hasOwnProperty);
// undefined, because d doesn't inherit from Object.prototype使用
class
创建1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
class Square extends Polygon {
constructor(sideLength) {
super(sideLength, sideLength);
}
get area() {
return this.height * this.width;
}
set sideLength(newLength) {
this.height = newLength;
this.width = newLength;
}
}
var square = new Square(2);
hasOwnProperty
这个属性定义在Object.prototype
上,是js中唯一一个处理对象属性且不会贯穿原型链的处理方法。
扩展原型链的方法比较
MDN上推荐使用下面两种方法进行原型链的扩展。不推荐使用Object.setPrototypeOf
以及__proto__
。
另外感觉class
也是一种实现扩展原型链的方法,感觉这里落下了。
- 传统的方法
1 | function foo() {} |
- 使用
Object.create
下面的例子显示,Object.create
可以传入第二个参数,表示添加到新创建对象的可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)。
1 | function foo() {} |
或者
1 | function foo() {} |
prototype
和Object.getPrototypeOf
当你调用1
var o = new Foo();
时,javascript实际执行的是1
2
3var o = new Object();
o.[[Prototype]] = Foo.prototype;
Foo.call(o);
全文完。