关键词:构造函数
、原型
、实例
、原型链
、继承
目录
原型:也称为实例原型,是一个对象,构造函数的
prototype
属性指向的就是原型,由构造函数创建的实例有个__proto__
属性,指向的也是原型
由原型组成的一条链,原型为一个对象,它有 __proto__
属性,指向父类的 prototype
属性
__proto__
:该属性是任何对象都有的属性
prototype
: 该属性是函数才有的属性
继承的本质:一个对象获取另一个对象的属性
一个对象的属性,通常是保存在原型上,所以说继承也可以说是子类原型获取父类原型属性
children.prototype = new Parent()
比如 react 中实现的继承
createClass: function(spec) {
var Constructor = function(initialProps, children) {
this.construct(initialProps, children);
};
Constructor.prototype = new ReactCompositeComponentBase();
Constructor.prototype.constructor = Constructor;
mixSpecIntoComponent(Constructor, spec);
invariant(
Constructor.prototype.render,
'createClass(...): Class specification must implement a `render` method.'
);
var ConvenienceConstructor = function(props, children) {
return new Constructor(props, children);
};
ConvenienceConstructor.componentConstructor = Constructor;
ConvenienceConstructor.originalSpec = spec;
return ConvenienceConstructor;
}
问题:为什么
Constructor.prototype.constructor = Constructor;
单独设置 constructor 属性呢?
答:在实例化后,实例.proto.constructor 指向的是原函数类。伪类继承,目的是完全获取父类 prototype 上的值,但是不想获取不该要的 constructor 属性。
var children = Object.create(obj)
,这里obj为直接对象 {}
在函数内部对 parent 对象操作,返回一个新对象 children,children 选择性获取 parent 的部分属性
说明:第3种方式与前2种有很大的区别,前2种都继承了父亲的所有属性,第三种继承部分父亲属性,并且可以隐藏操作细节,不允许实例直接访问属性值,实现对父亲属性的保护,通过闭包。
time: 2019.01.22
class Parent {
constructor() {}
}
class children extends Parent {
constructor() {
super()
}
}
function Hello() {}
Hello.prototype.world = 'hello world';
const hello = new Hello()
原型,怎么获取原型,怎么看?
构造器 Hello.prototype 和实例 hello.proto 属性都是指向原型对象
原型对象:包含构造器和 proto 属性,该属性指向 Object,构造器就是 Hello 函数。
{
world: "hello world",
Constructor: Hello(),
__proto__: Object
}
prototype 是只存在于构造器中,实例不具备这个属性,实例具有 proto 属性,指向原型对象。
所以说,构造器的 prototype 属性和实例的 proto 属性,都指向原型对象。
构造器也是 Function 的实例,它自然也有原型对象 Hello.__proto__ === Function.prototype;//true
问: 构造器的 proto 属性,与构造器原型对象的 proto 属性什么关系?
答: 并没有什么关系。构造器原型对象的 proto 指向的是 Object 的原型对象。反而构造器原型对象的 constructor 的 proto 属性,它就是构造器的 proto 属性,即 Hello.__proto__ = Hello.prototype.constructor.__proto__
以往访问对象原型对象,可以通过构造函数的 prototype
属性访问,也可以通过实例对象的 __proto__
属性访问
es6 在全局对象 Object 上新增了2个方法:
- Object.getPrototypeOf() 获取对象的原型
- Object.setPrototypeOf() 设置对象的原型
问题:能使用 setPrototypeOf 方法在 function 构造函数上吗?
答:不能。通常在 function 构造函数上使用 prototype 属性访问原型对象,在实例对象上使用 __proto__
属性访问构造函数的原型对象,但是也可以使用 getPrototypeOf 访问实例对象的原型对象。