JavaScript面向对象---原型与原型链

一、理解

1、什么是原型?

           在JavaScript中原型是一个prototype对象,用于表示类型之间的关系。

2、什么是原型链?

           原型链是针对构造函数的,比如我先创建了一个函数,然后通过一个变量new了这个函数,那么这个被new出来的函数就会继承创建出来的那个函数的属性,然后如果我访问new出来的这个函数的某个属性,但是我并没有在这个new出来的函数中定义这个变量,那么它就会往上(向创建出它的函数中)查找,这个查找的过程就叫做原型链。

  Object ==> 构造函数1 ==> 构造函数2

  就和css中的继承一样,如果自身没有定义就会继承父元素的样式。


二、__proto__ 与 prototype

1)、prototype(函数的原型对象):函数才有prototype,而且所有函数必有prototype。prototype是一个对象,指向了当前构造函数的引用地址呢。

2)、 __proto__(对象的原型):对象才有__proto__,而且所有对象必有__proto__属性(这里的对象除了我们理解的狭义对象,也包括了函数、数组等对象)。当用构造函数实例化(new)一个对象时,会将新对象的__proto__属性,指上构造函数的prototype。

来看个案例:

function Person(){
    //  do something
}
var zhangsan = new Person();
console.log(zhangsan.__proto__ == Person.prototype);     // true

【解释】上例中,我们使用函数Person,new出了一个对象zhangsan。 那么对象zhangsan(类似Java对象)的__proto__就等于函数Person(类似Java类)的prototype。


三、原型的作用是什么?

1.数据共享 节约内存内存空间
2.实现继承

下面我将举例说明为什么要使用原型:

function Person(name) {
    this.name=name;
    this.eat=function () {
        console.log(this.name+"吃东西");
    }
    this.sleep=function () {
        console.log(this.name+"睡觉");
    }
}
var p1=new Person("小明");
p1.eat();        //小明吃东西
p1.sleep();        //小明睡觉

var p2=new Person("小利");
p2.eat();        //小利吃东西
p2.sleep();        //小利睡觉

console.dir(p1);    //dir()打印结构
console.dir(p2);

四、原型链的四大准则

① 通过构造函数,new出的对象,新对象的__proto__指向构造函数的prototype

② 所有函数的__proto__ 指上Function()的prototype

③ 非构造函数new出的对象( {} new Object() 对象的prototype)的__proto__指向Object的prototype

④ Object的prototype的__proto__指向null


五、prototype对象

js中函数具有两重性:首先,函数可以划分作用域,一个函数就是一个执行环境(这也是个大话题,本文暂不提)。其次,一个函数也是一个对象,属Function类型。既然是对象,就可以有属性和方法,而原型(prototype)就是函数的一个属性。

下面的代码定义了一个函数:

function Daddy(name){ 
    this.name = name
}

看上去只是添加了一个属性,但它背地里还偷偷地做了点坏事,我现在把它揭露出来,上面代码和下面代码的执行结果可以认为是一致的:

function Daddy(name){
    this.name = name
}
Daddy.prototype = {};
Daddy.prototype.constructor = Daddy;

我们来看看它到底偷偷做了些啥:

  1. 在定义一个函数后,立马为这个函数添加一个prototype属性。
  2. prototype属性被赋予一个Object对象,现在prototype也成为对象了。
  3. 为prototype对象添加constructor属性,并指向函数Daddy本身。

所谓的”原型”、”原型对象”这些名词,说的就是此刻的prototype对象。


六、prototype和__proto__的区别是什么?


七、通过new关键字理解prototype和__proto__

下面将以var fun=new Function();为例简单的了解下new的过程中究竟干了个嘛?

new Function()={
var fun={};
fun.__proto__=Function.prototype;
var result=Function.call(fun);
return typeof result==='Function'?result:fun;
}

 不难看出其实在new对象时不是简单的返回一个对象,中间经历了核心的三步:

        1.首先就是创建一个同名的空的fun对象;

        2.紧接着就是把Function上的prototype属性赋给fun对象的__proto__属性(这里不知道这个是什么没有关系就知道进行了这么一步,后面讲解prototype,__proto__时会详细介绍);

        3.使用fun替换Function的上下文context

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值