JS原型相关

158 阅读1分钟

个人对于原型链的相关东西一直处于一个很混乱的状态,一直没找时间梳理,春节之际给自己放个假,也整理下自己想看的东西

相关书籍《你不知道的JavaScript上卷》

  • for...in会遍历原型链上所有属性

属性的设置和屏蔽

假设有一个对象myObj,执行语句

myObj.foo = "a";

可能出现的几种情况:

  • 如果myObj的原型链和myObj都没有这个属性,则会直接添加到myObj上
  • 如果myObj有改属性,则会修改已有属性
  • 如果foo存在在原型链上,并且没有被标记为只读,则会直接在myObj上添加一个foo,他会屏蔽原型链上的foo
  • 如果foo存在在原型链上,并且被标记为只读,则无法修改该属性,也无法赋值
  • 如果foo存在在原型链上且是一个setter,则会调用,不会添加到myObj上

"类"函数

经常看到这种写法

function Foo () {};
var a = new Foo();

这里执行new的这一步实际是将a的原型链指向Foo.prototype,注意这里比较坑的是new的时候并不是复制Foo.prototype而是直接指向,所以如果new多个对象,他们所有的原型链都指向同一个对象!

"构造函数"

function Foo () {};
var a = new Foo();
Foo.prototype.constructor === Foo; //true
a.constructor === Foo;

使用Object.create()继承

Object.create()会创建一个新对象,并把该对象的原型链关联到指定对象上;

// Object.create()的polyfill代码
if (!Object.create) {
    Object.create = function (obj) {
        function F () {}
        F.prototype = obj;
        return new Foo();
    }
}

检查“类”的关系

  • 通过instanceof
function Foo () {}
Foo.prototype.blah = 'a';
var a = new Foo();
a instanceof Foo //true;

这里判断的是a的原型链是否有指向Foo.prototype;

几个方法

  • Object.isPrototypeOf();
  • Object.getPrototypeOf();