js原型和原型链

本文深入探讨了JavaScript中对象的概念,包括普通对象与函数对象的区别,解析了原型对象及其作用,并详细介绍了原型链的工作原理。

一.普通对象与函数对象

JavaScript 中万物皆对象!但对象也是有区别的。分为普通对象和函数对象。

function f1(){};
 var f2 = function(){};
 var f3 = new Function();

 var o1 = {};
 var o2 =new Object();
 var o3= new f1();

 console.log(typeof o1); //object
 console.log(typeof o2); //object
 console.log(typeof o3); //object
 console.log(typeof f1); //function
 console.log(typeof f2); //function
 console.log(typeof f3); //function 

以上,o1,o2,o3为普通对象;f1,f2,f3为函数对象。o1,o2是创建对象的两种常见形式,那为什么o3不是函数对象呢?因为它不是由new Function()创建的。

注:var o4 = Object(); console.log(typeof o4);//object
这类内置对象使用new或者直接调用方式都能构建出一个新的数据类型。但是构建出来的数据有区别的。

console.log(typeof Function); //function
console.log(typeof Object); //function
console.log(typeof Number); //function
console.log(typeof Boolean); //function
console.log(typeof String); //function
console.log(typeof Array); //function
console.log(typeof RegExp); //function
console.log(typeof Error); //function
console.log(typeof Date); //function

javascript中需要通过new来创建的内置对象也都是函数对象,其本质也是通过new Function()创建的。

二. 原型对象

在JavaScript 中,每当定义一个对象(函数)时候,对象中都会包含一些预定义的属性。其中函数对象的一个属性就是原型对象 prototype。每个函数对象都有 prototype(Function.prototype除外)

除了Function.prototype,其他常见原型对象都是普通对象。

    console.log(typeof Object.prototype);   // object
    console.log(typeof Number.prototype);   // object
    console.log(typeof Boolean.prototype);  // object
    console.log(typeof String.prototype);   // object
    console.log(typeof Array.prototype);    // object
    console.log(typeof RegExp.prototype);  // object
    console.log(typeof Error.prototype);    // object
    console.log(typeof Date.prototype);     // object
    console.log(typeof Function.prototype); // function

下面来看看我们自定义的函数对象的prototype

    function f(){};
    console.log(f.prototype);//f()
    console.log(typeof f.prototype); 

结果是
这里写图片描述

从结果中我们可以看出f.prototype是一个原型对象。其中constructor返回创建此对象的函数。

下面来说一下prototype的作用:共用
如果了解工厂模式,那么你就很清楚prototype的好处,它能使公用的方法或者属性在内存中存在一份 ,从而提高性能。

function Animal(name){
    this.name = name;
    this.showName = function(){
        console.log( this.name );
    };
}
var a1 = new Animal('bobo');
var a2 = new Animal('qiqi');

console.log(a1.showName);
console.log(a2.showName);
console.log( a1.showName == a2.showName );  //false

这里写图片描述

看似是同一个函数,但实际上是分别在a1和a2指向的内存地址中。但由于函数是一样的,没有必要重复创建,所以prototype就派上用场啦。
将上面代码改成:

function Animal(name){
    this.name = name;
}
Animal.prototype.showName = function(){
    console.log( this.name );
};
var a1 = new Animal('bobo');
var a2 = new Animal('qiqi');

console.log(a1.showName);
console.log(a2.showName);
console.log( a1.showName == a2.showName );  //true

这里写图片描述

三.原型链

javascript在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。以上面的例子来说

    console.log( a1.__proto__ == Animal.prototype);             //true
    console.log(Animal.prototype.__proto__ == Object.prototype);//true
    console.log(Object.prototype.__proto__ == null);            //true

这里写图片描述

总结:
1.对象均有属性__proto__,指向该对象的构造函数的原型对象。
2.函数对象除了有属性__proto__,还有属性prototype,prototype指向该方法的原型对象。

本文参考http://www.108js.com/article/article1/10201.html?id=1092(侵立删)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值