资讯专栏INFORMATION COLUMN

js原型链1

Baaaan / 924人阅读

摘要:系列文章原型链原型链函数对象和普通对象中,万物皆对象。原型对象在中,每当定义一个对象,对象中都会有一些预定义的属性。参考文章原型与原型链终极详解附自己理解的原文章中的内存分析图

系列文章:

js原型链1
js原型链2

1. 函数对象和普通对象

js中,万物皆对象。对象分为函数对象和普通对象。记住Object和Function是js自带的函数对象。

console.log(typeof Object); //function
console.log(typeof Function); //function

函数对象是function;普通对象是object。下面看常用的几种生成对象的方法:

var o1 = {};
var o2 = new Object;
var o3 = new Object();
var o4 = new Object(undefined);
var o5 = new Object(null);
var o6 = Object.create(Object.prototype);
var o7 = Object.create(null);
console.log(typeof o1); // object
console.log(typeof o2); // object
console.log(typeof o3); // object
console.log(typeof o4); // object
console.log(typeof o5); // object
console.log(typeof o6); // object
console.log(typeof o7); // object

function f1(){};
var f2 = function(){};
var f3 = new Function("str","console.log(str)");
console.log(typeof f1);// function
console.log(typeof f2);// function
console.log(typeof f3);// function

var o8 = new f1();
console.log(typeof o8);// object

记住,凡是通过new Function()或function关键字创建的对象都是函数对象,其他是普通对象。Object和Function也都是通过new Function()创建的。

2. 原型对象

在js中,每当定义一个对象,对象中都会有一些预定义的属性。其中函数对象的一个属性就是原型对象prototype;普通对象没有prototype,但有__proto__属性。打印o1-o8发现,除了o7其他都一样。

o7:
Object{No Properties} 

其他:
Object{__proto__: Object}

而f1-f3却都不一样。

f1: function f1(){}
f2: function (){} // 匿名函数
f3: function anonymous(str/**/) { // anonymous意思是匿名
        console.log(str)
    }

发现打印不出prototype,我们直接打印prototype试试:

console.log(typeof f1.prototype);console.log(f1.prototype);
结果如下:
object
Object{constructor: f1(), __proto__: Object}

console.log(typeof f2.prototype);console.log(f2.prototype);
结果如下:
object
Object{constructor: (),__proto__: Object}

console.log(typeof f3.prototype);console.log(f3.prototype);
结果如下:
object
Object{constructor:anonymous(str/**/),__proto__:Object}

再打印Object.prototype和Functjion.prototype试试

console.log(typeof Object.prototype);console.log(Object.prototype);
结果如下:
object
Object{
    __defineGetter__:__defineGetter__()
    __defineSetter__:__defineSetter__()
    __lookupGetter__:__lookupGetter__()
    __lookupSetter__:__lookupSetter__()
    constructor:Object()
    hasOwnProperty:hasOwnProperty()
    isPrototypeOf:isPrototypeOf()
    propertyIsEnumerable:propertyIsEnumerable()
    toLocaleString:toLocaleString()
    toString:toString()
    valueOf:valueOf()
    get __proto__:__proto__()
    set __proto__:__proto__()
}

console.log(typeof Function.prototype);console.log(Function.prototype);
结果如下:
function
function () {}
3. 原型对象的作用
var person = function(name){
this.name = name
};
person.prototype.getName = function(){
 return this.name; 
}

var zzz = new person("zzz");
console.log(zzz.getName()); // zzz

原型链中增加一个函数,他的实例就可以直接使用这个函数了。

4. 原理

js在创建对象的时候都有一个__proto__属性,指向创建它的函数的prototype属性。

1. console.log(zzz.__proto__ == person.prototype);// true
2. console.log(person.__proto__ == Function.prototype);// true
3. console.log(person.prototype.__proto__ == Object.prototype);// true
4. console.log(Object.__proto__ == Function.prototype);// true
5. console.log(Function.__proto__ == Function.prototype);//true
6. console.log(Function.prototype.__proto__ == Object.prototype);//true

分析1:zzz是person创建的,所以person.__proto__指向person.prototype.
分析2:person是Function创建的,所以person.__proto__指向Function.prototype.
分析3:person.prototype是个对象,是Object创建的。
分析4:Object是Function创建的。
分析5:Function也是自己创建的,比较特殊。
分析6:Function的prototype是对象,Object创建的。

总结:

1. 有prototype都是object,所以所有prototype的__proto__都指向Object的prototype。
2. Object的prototype的__prototype__特殊,指向null.
3. Function的__proto__也比较特殊,指向自己的prototype.

图解如下:

另外,原型对象prototype中都有一个constructor属性,用来引用他的函数对象,即。

person.prototype.constructor === person;// true
5. 参考文章

JS原型与原型链终极详解
附自己理解的原文章中的内存分析图:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81641.html

相关文章

  • JS基础-原型原型真的不能一知半解

    摘要:原型链和对象的原型是对象实例和它的构造函数之间建立的链接,它的值是构造函数的。对象的原型根据上文提到的构造调用函数的时候会创建一个新对象,自动将的原型指向构造函数的对象。 showImg(https://segmentfault.com/img/remote/1460000020185197); JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清...

    changfeng1050 评论0 收藏0
  • 理解js原型与继承

    摘要:相当于在用原型继承编写复杂代码前理解原型继承模型十分重要。同时,还要清楚代码中原型链的长度,并在必要时结束原型链,以避免可能存在的性能问题。 js是一门动态语言,js没有类的概念,ES6 新增了class 关键字,但只是语法糖,JavaScript 仍旧是基于原型。 至于继承,js的继承与java这种传统的继承不一样.js是基于原型链的继承. 在javascript里面,每个对象都有一...

    wthee 评论0 收藏0
  • js原型 原型 原型的继承

    摘要:图片描述缺点是无法实现多继承可以在构造函数中,为实例添加实例属性。 对象的方法 Object.assign() 对象可以简写 ,如果 key 和 value 相等则可以简写 let name = xm; let age = 2; let obj = { name, age, fn(){ // 可以省略函数关键字和冒号: console.log(2...

    soasme 评论0 收藏0
  • 从实现角度分析js原型

    摘要:从实现角度分析原型链欢迎来我的博客阅读从实现角度分析原型链网上介绍原型链的优质文章已经有很多了,比如说作为补充,就让我们换个角度,从实现来分析一下吧本文假设你对原型链已经有所了解。 从实现角度分析js原型链 欢迎来我的博客阅读:《从实现角度分析js原型链》 网上介绍原型链的优质文章已经有很多了,比如说: https://github.com/mqyqingfeng/Blog/issu...

    CompileYouth 评论0 收藏0
  • js原型

    摘要:构造函数,实例,原型三者的关系如下图构造函数是构成整个原型链的关键,是他利用将原型传给了后代。因此,通过操纵构造函数的,就能够操纵原型链,从而对原型链进行自在的拼接。 要理解js的原型链主要就是理清楚以下三者的关系: 构造函数的protitype属性 对象的__proto__属性 对象的constructor属性 在js中,函数作为一等公民,它是一个对象,可以拥有自己的属性,可...

    NervosNetwork 评论0 收藏0
  • 温故js系列(15)-原型&原型&原型继承

    摘要:给添加属性给的原型对象添加属性原型链在中,每个对象都有一个属性,其保存着的地址就构成了对象的原型链。实例变量实例函数原型链继承有了原型链,就可以借助原型链实现继承。是中唯一一个处理属性但是不查找原型链的函数。 前端学习:教程&开发模块化/规范化/工程化/优化&工具/调试&值得关注的博客/Git&面试-前端资源汇总 欢迎提issues斧正:原型&原型链&原型继承 JavaScript-原...

    Ethan815 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<