1、typeof(是个运算符)
typeof '变量';
返回值:
number
string
boolean
undefined
object
2、instanceof(用于实例与构造函数间)(是个运算符)
var arr = [];
console.log(arr instanceof Array); //true
返回值:
true/false
3、isPrototypeOf()(用于实例与原型对象间)(是个函数,是个方法)
var arr = [];
console.log(Array.prototype.isPrototypeOf(arr)); //true
console.log(Object.prototype.isPrototypeOf(arr)); //true
console.log(Object.prototype.isPrototypeOf(Array.prototype)); //true
console.log(arr.prototype.isPrototypeOf(arr)); //false
返回值:
true/false
实例的原型和构造函数的原型还是有点不一样的,最起码看书上的符号就有区别
constructor | instance |
---|---|
superType | instance = new superType() |
prototype | [[prototype]] |
实例与构造\具体表现 | 具体对象 | 原型写法
|— |— |—
constructor | superType() | prototype |
instance | instance = new superType() | [[prototype]]/prototype
这里面有个小小的问题,表格到底怎么设计一目了然,什么作为行什么作为列?
4、prototype
、_prototype_
、Object.getPrototypeOf()
关系的理解
prototype
用于构造函数:
Array.prototype
_proto_
用于实例(这是个内部属性,实际中没有这样用),其实实例的原型有多种表示法,还有可以像上面这样的[[prototype]]
arr._proto_/arr.[[prototype]]
Object.getPrototypeOf()
取的也是实例的原型对象。因为上述用法在实际中不存在,所以才有了这个方法
Object.getPrototypeOf(arr) === Array.prototype;
实例理解:
当你执行:
var o = new Foo();
实际执行:
var o = new Object(); //对象从原始的Object来
o_prototype_ = Foo.prototype; //实例的原型指向构造函数原型,获得方法
Foo.call(o); //函数方法调用,传入对象,获取`属性`
==上述这样理解很透彻==
当你这样查找属性时:
o.someProp;
实际执行:检查自身有没有属性,如果没有,就查找Object.getPrototypeOf(o).someProp
;如果没有,就查找Object.getPrototypeOf(Object.getPrototypeOf(o)).someProp
;一直就这样找下去,找不到就返回null
==原型对象也是对象实例,这就是原型继承存在的依据所在==
==5、一个更重要的方法Object.setPrototypeOf(obj, newPrototye)
==
参考资料上说:更改实例对象的原型会是一个很慢的操作,更改了继承的性能也会受到影响。但目前来说,它的确解决了我目前最迫切的问题:
function ClassB(sColor, sName) {
this.name = sName;
Object.setPrototypeOf(this, new ClassA(sColor));
}
总结:[[prototype]]
、_proto
、Object.getPrototypeOf()
、Object.setPrototypeOf(obj, newPrototype)
这些原型属性都是和对象实例有关的。有了这些,就能清晰地理解构造函数的原型与实例对象的原型了。