Javascript 原型链

Javascript 原型链

本来想写一篇“如何用JS实现面向对象”,发现自己对prototype原型链还是有很多的不理解的地方。先看一张原型链关系图:

图片来自mollypages.org。

prototype属性

prototype是所有函数都有的一个属性。

function Man() {}
console.log(Man.prototype); // Object{}

prototype 属性使您有能力向对象添加属性和方法。在每个使用每个对象的属性或方法时,js会按照原型链的顺序查找属性,直到找到。

function employee(name,job,born) {
    this.name=name;
    this.job=job;
    this.born=born;
}

var bill = new employee("Bill Gates","Engineer",1985);

employee.prototype.salary=null;
bill.salary=20000;

console.log(bill.salary); //20000

注意对象是没有prototype属性的,只有函数有。但是一些特有的浏览器(firefox,chrome)通过proto属性暴露了原型prototype,如上图。

new关键字

new用于新建一个对象,例如:

function Man() {}
var m = new Man();

下面的代码用js模拟了new操作:

function newObj(Fun,arguments) {
    var o = {};
    if (Fun && typeof Fun === "function") {
        o.__proto__ = Fun.prototype;
        Fun.apply(o, arguments);
        return o;
    }
}

从代码中可以看出,首先新建一个对象o,然后修改proto指向Fun.prototype,然后以o为上下文(context)执行Fun函数,最后返回o。因为对象的proto设置是在new操作中的,所以导致了以下现象:

function Man() {}
function Father() {
    this.name=""
}
var m = new Man();
Man.prototype = new Father();
console.log(m.name); // undefine

至此我们理解了图中的第一层,接下来讲第二、三层。

为何Foo.proto !== Foo.prptotype?

这里Foo函数可以看成是Function函数的对象!按照图中第一层的逻辑:对象的proto指向其函数的prototype属性,Foo的proto应该等于Function.prototype。

那么为什么Function函数和Object函数的proto都等于Function.prototype呢?

注意Function和Object都是函数,而所有的函数都是Function函数的对象(有点绕)!所以同上,它们的proto应该等于Function.prototype。

为什么o1与o2的proto等于Object.prototype呢?

原因与第一层的结构一样,o1,o2是Object函数的对象。

注意:Function.prototype与Foo.prototype同样是对象,它们也是通过Object函数构建的,所以它们的proto也等于Object.prototype。

Object.prototype

Object.prototype值是无法修改,它提供了一些默认的方法。且它的proto等于null!

function Man(){
    this.oo = "11";
}
Object.prototype = new Man();
console.log(Object.prototype.oo); //undefine

理解Javascript的原型链的重点在于对象、函数、函数的prototype,函数与函数的prototype同时也是对象。

在JavaScript语言中,所有对象的原型链根节点都是Object.prototype。

instanceof操作符

instanceof是一个二元运算符,如:A instanceof B. 其中,A必须是一个合法的JavaScript对象,B必须是一个合法的JavaScript函数 (function). 判断过程如下:

如果函数B在对象A的原型链 (prototype chain) 中被发现,那么instanceof操作符将返回true,否则返回false.

所以导致了:

Function instanceof Object;     //true
Object instanceof Function;     //true
Function instanceof Function;   //true
Object instanceof Object;       //true

这样的情况发生!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

【选择题】Java基础测试七

【选择题】Java基础测试七 86.欲构造ArrayList类的一个实例,此类继承了List接口,下列哪个方法是正确的?( B ) A、ArrayList m...

65430
来自专栏我是攻城师

Java基础类String了解一下

当你路过一些商场或者地铁口的时候,有没有被千篇一律的"xx健身,了解一下" 所烦到。

11820
来自专栏向治洪

Swift基础语法

本文来自Swift中文开发组,感谢翻译者的分享。 本文将分几部分对Swift对iOS的语法做讲解。本文为第一节,主要讲解基础语法。 常量和变量 常量和变量把一个...

19860
来自专栏大数据钻研

JavaScript 知识点整理

JavaScript是按照ECMAScript标准设计和实现的,后文说的JavaScript语法其实是ES5的标准的实现。 先说说有哪些基础语法? 最基础语法有...

29150
来自专栏编程

Kotlin学习之常用高阶函数:filter

Kotlin学习之常用高阶函数:filter Kotlin高阶函数一般是数组、集合、序列等数据结构的扩展函数,接收一个操作函数对数据进行操作,在Kotlin函数...

240100
来自专栏开发与安全

从零开始学C++之从C到C++(一):const与#define、结构体对齐、函数重载name mangling、new/delete 等

一、bool 类型 逻辑型也称布尔型,其取值为true(逻辑真)和false(逻辑假),存储字节数在不同编译系统中可能有所不同,VC++中为1个字节。 声明方式...

20100
来自专栏Java帮帮-微信公众号-技术文章全总结

第十三天 面向对象-final static 匿名对象内部类包代码块【悟空教程】

15240
来自专栏机器学习入门

LWC 60:736. Parse Lisp Expression

LWC 60:736. Parse Lisp Expression 传送门:736. Parse Lisp Expression Problem: You a...

23370
来自专栏开发与安全

从零开始学C++之类与对象:类声明、类作用域、前向声明、this指针、嵌套类、PIMPL 技法 等

一、类声明 //类是一种用户自定义类型,声明形式: class 类名称 {    public:              公有成员(外部接口)   ...

24600
来自专栏我和未来有约会

Js中的变量

Js中的变量:  1:如果在var中没有初始化变量的值,则默认为undefined.  2:可以不用var来申明一个变量,但是在过程级中申明一个变量时,就必须用...

29060

扫码关注云+社区

领取腾讯云代金券