首页 > 代码库 > JavaScript原型学习笔记

JavaScript原型学习笔记

1、“一切都是对象”这句话的重点在于如何去理解“对象”这个概念。

——当然,也不是所有的都是对象,值类型就不是对象。

函数也是一种对象。他也是属性的集合,你也可以对函数进行自定义属性。

2、每个函数一个属性——prototype。对,每个函数都有一个属性叫做prototype。

 这个prototype的属性值是一个对象(属性的集合),默认的只有一个叫做constructor的属性,指向这个函数本身。而constructor属性的属性值(方法)比较常见的有:hasOwnProperty(),isPrototypeOf()等等

(嘿嘿,这里就先暂时举例这些,其他的:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype)

每个对象都有一个隐藏的属性——“__proto__”,这个属性引用了创建这个对象的函数的prototype。即:fn.__proto__ === Fn.prototype;

(每个函数function都有一个prototype,即原型。这里再加一句话——每个对象都有一个__proto__,可成为隐式原型。);

每个函数的prototype属性,这个属性是一个指针,指向一个对象;这个对象的用途是共享特定类型的所有实例属性和方法;

function Test(){            Test.prototype.name="spezz07";            Test.prototype.age=23;            Test.prototype.message=function(){                alert(this.name);            }        }    var test1=new Test();    test1.message();//spezz07    var test2=new  Test();    console.log(test2.age)//23    console.log(test1.age===test2.age)//true

新对象的属性和方法都是共享的;

我们可以通过对象实例来访问原型中的值,但不能通过对象实例改写原型中的值,如果在实例添加了一个属性与其原型中的其中一个属性同名的话,那我们就在该实例中创建该属性;而原型中的那个属性就会被屏蔽。

function Test(){            Test.prototype.name="spezz07";            Test.prototype.age=23;            Test.prototype.message=function(){                alert(this.name);            }        }    var test1=new Test();    test1.age=24;    console.log(test1.age)//24 来自实例    var test2=new  Test();    console.log(test2.age)//23  来自原型

在test1中,在实例中找到了age这个属性,于是就返回了,不必就往上一级去寻找(作用链相关);而test2,在实例中没有找到,于是就往上一级寻找了。

当然这个实例属性只会阻止我们访问原型的“那个属性”,但不会修改原型中的“那个属性”;不过如果我们使用delete 操作符的话,则可以完全删除实例中的属性,从而能重新访问到原型中的“那个属性”;

   function Test(){            Test.prototype.name="spezz07";            Test.prototype.age=23;            Test.prototype.message=function(){                alert(this.name);            }        }        var test1=new Test();        test1.age=24;        console.log(test1.age)//24 来自实例        var test2=new  Test();        console.log(test2.age)//23  来自原型;        delete test1.age;        console.log(test1.age)//23 来自原型

 

3、js的中的继承

javascript中的继承是通过原型链来体现的。先看几句代码

 function Foo(){};    var f1=new Foo();    f1.a=10;    Foo.prototype.a=100;    Foo.prototype.b=200;    console.log(f1.a)//10;    console.log(f1.b)//200

以上代码中,f1是Foo函数new出来的对象,f1.a是f1对象的基本属性,f1.b是怎么来的呢?——从Foo.prototype得来,因为f1.__proto__指向的是Foo.prototype

访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着__proto__这条链向上找,这就是原型链。

那么我们在实际应用中如何区分一个属性到底是基本的还是从原型中找到的呢?大家可能都知道答案了——hasOwnProperty,特别是在for…in…循环中,一定要注意。

注意:f1的这个hasOwnProperty方法是从哪里来的? f1本身没有,Foo.prototype中也没有,哪儿来的?

它是从Object.prototype中来的,请看图:

技术分享

对象的原型链是沿着__proto__这条线走的,因此在查找f1.hasOwnProperty属性时,就会顺着原型链一直查找到Object.prototype。

 由于所有的对象的原型链都会找到Object.prototype,因此所有的对象都会有Object.prototype的方法。这就是所谓的“继承”。

注意:__proto__默认的也有指向。它指向的是最高级的object.prototype,而object.prototype的__proto__为空。(object.prototype__proto__===null)

 

JavaScript原型学习笔记