初学JavaScript之猜测new操作符的原理

本文是一篇原理猜测的文章,如果有不准确的地方请指正,转载请声明出处,谢谢!

原文:http://blog.csdn.net/softmanfly/article/details/34833931
点击跳转

JavaScript中构造函数与普通函数其实没有什么差别,构造函数可以当做普通函数来使用,普通函数也可以用new来模拟构造函数的调用,然而使普通函数与构造函数发生区别的其实就在于new操作符的内部原理,下面是我通过测试猜测的new操作符的执行过程,当你在用new操作符来生成一个对象时内部可能执行了以下几个步骤的操作:

以构造函数

function Person(name){

this.name = name

this.sayName = function() {

alert(this.name);

}

}

来举例说明:

(1) 新建一个对象 var object = {};

(2) 然后设置构造函数的作用域为object,这样就能使用this指针,具体的操作可能是这样的:

Person.apply(object,name);

(3) 执行构造函数中的具体代码,由于上一步apply使用的作用域是object,所以当执行this.name = name时其实执行器先是去寻找object中有没有name属性,没有name属性就添加一个name属性,并为他赋值。

(4) 返回这个创建的object;

(5) 当执行完构造函数之后,构造函数对象(注意措辞)中的this指针又变成了undefined,当再次调用这个函数时,执行器首先看看这个函数中的this指针是否有值,如果没有值他就会到作用域链的上一级去寻找this指针的值,直到找到this指针为止。如果这段话不好理解可以看如下的代码:

var p = new Person("cat");

window.sayName = p.sayName;

window.sayName();

最终其实输出的是undefined为什么呢?

因为 当调用window.sayName时,要alert一个this.name,执行器先去寻找sayName函数中的this属性是不是有值,结果发现没有值,然后去寻找他的调用者window对象的this指针,window的this指向window对象本身,但是遗憾的是window中并没有name这个属性,如果你在window的作用域下加上var name="Dog"的话,上面的代码就会输出dog,而不是cat.这就是this指针的一个搜索过程。

如果你调用window.sayName = p.sayName.bind(p);然后再去调用window.sayName的话,输出就变成了cat,这是因为你把一个新的sayName对象(因为bind返回的是一个新的对象)的this指针绑定到了p对象上,即this指向p对象,当你再调用window.sayName()时搜索sayName函数对象的this指针就不再是undefined了,而是p,此时就直接输出了cat.

初学JavaScript之猜测new操作符的原理,布布扣,bubuko.com

时间: 2024-12-29 12:39:23

初学JavaScript之猜测new操作符的原理的相关文章

Javascript属性constructor/prototype的底层原理

在Javascript语言中,constructor属性是专门为function而设计的,它存在于每一个function的prototype属性中.这个constructor保存了指向function的一个引用.在定义一个函数(代码如下所示)时, function F() { // some code } JavaScript内部会执行如下几个动作: 为该函数添加一个原形属性(即prototype对象). 为prototype对象额外添加一个constructor属性,并且该属性保存指向函数F的

为什么不要在 JavaScript 中使用位操作符?

如果你的第一门编程语言不是 JavaScript,而是 C++ 或 Java,那么一开始你大概会看不惯 JavaScript 的数字类型.在 JavaScript 中的数字类型是不区分什么 Int,Float,Double,Decimal 的.咳咳,我说的当然是在 ES6 之前的 JS,在 ES6 的新标准中提出了像 Int8Array 这样新的数据类型.不过这不是本文叙述的重点,暂且就不谈啦.本文将更着重地谈 JS 的数字类型以及作用于它的位操作符,而关于包装对象 Number 的更多了解可以

点滴的积累---初学Javascript

在学习知识的路上,我们需要的不断的去接触新的知识,同时我们也不要不停地对自己旧的知识进行总结.最近通过<牛腩Javascript>和姜昊的<Javascript专题视频>对Javascript有了初步的理论了解. Javascript学习简介 由于Javascript是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言.因此在学习Javascript时需要具备一定的对象对象基础,由于已经学习过C#和VB.NET因此在学习的过程中理解起来还是相对容易的. 同时JavaScript

PHP和Javascript中的逻辑操作符&amp;&amp;和||的比较

几乎所有的语言都有&&(且)和||(或)的逻辑操作符,&&用于判断多个表达式的时候,如果为真(true),则继续判断下一个表达式,如果为假(false),则停止表达式解析,即只有当所有表达式都为真(true),才返回真(true),如果某一个表达式为假(false),则结果就(false):而||(或)恰好相反,也是对多个表达式依次判断,如果表达式为真(true),则终止表达式的逻辑判断,其结果为真(true).这两个逻辑操作符都存在短路这个行为: &&判断

初学JavaScript七大注意事项

知识说明: 初学JavaScript,注意以下七大细节,在实现同样功能的情况下,让我们的代码更易懂.效率更高. 一.简化代码 例如:创建对象 之前是这样的: Var car = new object(); Car.color = “red”; Car.wheels = 4; Car.age = 8; 而现在可以写成这样子: Var car = {color:’red’, wheels:4, age:8} 例如:创建数组 之前是这样的: Var studentArray = new Array(‘

javaScript数据类型与typeof操作符

1,typeof操作符. typeof操作符是用来检测变量的数据类型.使用:typeof  变量名;返回以下字符串: 字符串 描述 undefined 未定义 boolean 布尔值 string 字符串 number 数值 object 对象或者null function 函数 2,undefined类型 undefined只是一个值.当我们声明一个变量,没有做初化的时候.我们调用这个变量就会返回一个值undefined.如: var name; alert(name);如果我们把alert语

javascript中new操作符的原理

javascript中的new是一个语法糖,对于学过c++,java 和c#等面向对象语言的人来说,以为js里面是有类和对象的区别的,实现上js并没有类,一切皆对象,比java还来的彻底 new的过程实际上是创建一个新对象,把新象的原型设置为构造器函数的原型,在使用new的过程中,一共有3个对象参与了协作,构造器函数是第一个对象,原型对象是二个,新生成了一个空对象是第三个对象,最终返回的是一个空对象,但这个空对象不是真空的,而是已经含有原型的引用(__proto__) 步骤如下: (1)    

深度剖析 javascript call方法实现继承的原理

call 方法是比常常见也是javascript 难点之一,以前只知道可以实现继承,但是没有深度研究过原理,网上大多数也只是说了方法,没有讲其中的原理,今天没事正好好好研究一下.call 方法最常见的也是面试问题之一是啥,对就是用call实现继承.以下是两个简单的实现继承的例子. demo1: function a(){ ??? this.name = function(){ ????? ?console.log('a',this.namevalue,this.age) ??? } } func

深入理解javascript作用域系列第一篇——内部原理

× 目录 [1]编译 [2]执行 [3]查询[4]嵌套[5]异常[6]原理 前面的话 javascript拥有一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则被称为作用域.作用域貌似简单,实则复杂,由于作用域与this机制非常容易混淆,使得理解作用域的原理更为重要.本文是深入理解javascript作用域系列的第一篇——内部原理 内部原理分成编译.执行.查询.嵌套和异常五个部分进行介绍,最后以一个实例过程对原理进行完整说明 编译 以var a = 2;为例,说明javasc