对象是 new 进去的,那到底产生了什么?
什么,看到这个题目,大吃一惊,程序员居然有对象?当然有啦,这都什么年代了。不信,你来看看有了对象之后,面试官就会问你到底产生了什么?
业余一点讲述:
new
是用来实例化一个类的,而后在内存中调配一个实例对象。
咱们先来看看一个例子:
function Person(name) { this.name = name;}Person.hairColor = "black";Person.prototype.say = function() { console.log("My name is " + this.name);};var ken = new Person("人生代码");console.log( ken.name, // "人生代码", ken.hairColor, // undefined ken.height // undefined);ken.say(); // "My name is 人生代码"console.log( Person.name, // "Person" Person.hairColor // "black");Person.say(); // Person.say is not a function
这段代码产生了什么?接下来就来揭晓答案
重点解析
第8行代码是要害:
var ken = new Person("人生代码");
Person
原本就是个一般的函数,只不过如果给他加了 new
操作,就变成了构造函数。
那么 JS
引擎在解析代码的时候,外部会做很多解决,伪代码如下:
new Person('人生代码') = { var obj = {}; // 定义对象 var proto = Object.create(Person.prototype); // 复制原型 obj.__proto__ = proto; // 建设原型链 // obj->Person.prototype->Object.protorype->null var res = Person.call(obj, '人生代码'); // 相当于 obj.Person('人生代码') // 如果无返回值或者返回一个非对象值,则将obj返回作为新对象: return typeof res === 'object' ? result || obj : obj;}
咱们能够得出以下几点:
obj.name
是在Person.call(obj, '人生代码')
之后才赋值的- 等到
obj
经返回被赋给ken
之后,ken.name
就是 '人生代码' 了
所以咱们能够画出以下原型链:
ken.name
: 长期变量obj
有name
,obj
经返回被赋给ken
,ken
的一些属性由此而来。ken.hairColor
:ken
实例对象 先查找本身的hairColor
,没有找到便会沿着原型链查找,在上述例子中,咱们仅在Person
对象上定义了hairColor
,并没有在其原型链上定义,因而找不到。ken.height
:ken
实例对象 先查找本身的height
,没有找到便会沿着原型链查找,原型链上也没有,因而找不到。ken.say
:ken
会先查找本身的say
办法,没有找到便会沿着原型链查找,在上述例子中,咱们在Person.prototype
上定义了say
,因而在原型链上找到了say
办法。- 另外,在
say
办法中还拜访this.name
,这里的this
指的是其调用者。如果ken
调用say
,ken
就是调用者,因而输入ken.name
的值。
总结
new 运算符创立一个用户定义的对象类型的实例或具备构造函数的内置对象的实例。new 关键字会进行如下的操:
- 创立一个空的简略
JavaScript
对象(即{}); - 链接该对象(即设置该对象的构造函数)到另一个对象 ;
- 将步骤1新创建的对象作为
this
的上下文 ; - 如果该函数没有返回对象,则返回
this
。
代码实现请参考以下链接:
https://github.com/sisterAn/JavaScript-Algorithms/issues/71