Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Javascript原型链 #2

Open
zmmbreeze opened this issue Aug 31, 2016 · 0 comments
Open

Javascript原型链 #2

zmmbreeze opened this issue Aug 31, 2016 · 0 comments
Labels

Comments

@zmmbreeze
Copy link
Owner

以前的旧文章转移到这里

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

ttt

图片来自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

这样的情况发生!

@zmmbreeze zmmbreeze added the blog label Aug 31, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant