注意
对象的原型(可以通过Object.getPrototypeOf(obj)或者已被弃用的__proto__属性获得)是每个实例上都有的属性,构造函数的prototype是构造函数的属性。也就是说,Object.getPrototypeOf(new Foobar())和Foobar.prototype指向着同一个对象
使用原型
默认的原型属性
function doSomething(){}
console.log( doSomething.prototype );
//doSomething 函数有一个默认的原型属性
//打印结果
{
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
复制代码
添加一些属性到 doSomething 的原型上面
function doSomething(){}
doSomething.prototype.foo = "bar";
console.log( doSomething.prototype );
//打印结果
{
foo: "bar",
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
复制代码
使用 new 运算符来在现在的这个原型基础之上,创建一个 doSomething 的实例
function doSomething(){};
doSomething.prototype.foo = "bar";
var Instance = new doSomething();
Instance.prop = "some value";
console.log( Instance );
//打印结果
{
prop: "some value",
__proto__: {
foo: "bar",
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
}
复制代码
必须重申,原型链中的方法和属性没有被复制到其他对象——它们被访问需要通过前面所说的“原型链”的方式
//定义一个构造器函数
function Person() {
// 属性与方法定义
};
//创建一个对象实例
var person1 = new Person();
//调用 person1 的“实际定义在 Object 上”的方法时
person1.valueOf();
复制代码
发生了如下过程:
1. 浏览器首先检查,person1 对象是否具有可用的 valueOf() 方法。
2. 如果没有,则浏览器检查 person1 对象的原型对象(即 Person构造函数的prototype属性所指向的对象)是否具有可用的 valueof() 方法。
3. 如果也没有,则浏览器检查 Person() 构造函数的prototype属性所指向的对象的原型对象(即 Object构造函数的prototype属性所指向的对象)是否具有可用的 valueOf() 方法。这里有这个方法,于是该方法被调用
constructor 属性
每个实例对象都从原型中继承了一个constructor属性,该属性指向了用于构造此实例对象的构造函数。
//在控制台中尝试下面的指令
person1.constructor;
//都将返回 Person() 构造器,因为该构造器包含这些实例的原始定义
复制代码