outline

  1. prototype 与 __proto__
  2. function 与 object
  3. new 到底发生了什么

prototype 与 __proto__

首先说下在JS中比较容易让人困惑的 prototype 和 __proto__ 
__proto__ 就是JavaScript中所谓的原型.

一个对象的 __proto__ 属性和自己的内部属性[[Prototype]]指向一个相同的值 (通常称这个值为原型),原型的值可以是一个对象值也可以是null(比如说Object.prototype.__proto__ 的值就是null).该属性可能会引发一些错误,因为用户可能会不知道该属性的特殊性,而给它赋值,从而改变了这个对象的原型. 如果需要访问一个对象的原型,应该使用方法Object.getPrototypeOf.

firefox、chrome等浏览器把对象内部属性[[Prototype]]用 __proto__ 的形式暴露了出来.(老版本的IE并不支持 __proto__ ,IE11中已经加上了 __proto__ 属性)

prototype 是function中特有的.什么意思呢?举个例子:

function A(name){
this.name = name;
}
console.dir(A);

我们得到如下结果:

首先看A是一个函数,自然A的原型链就应该指向一个函数对象.

其次我们还看到当我们定义了function A的时候,A上会有一个 prototype 的属性.这个属性是我们定义function的时候就默认带上的.A的 prototype 指向一个对象,这个对象的包含一个 constructor 属性以及一个 __proto__ ( __proto__ 指向Object表示这是一个对象).默认的constructor属性指向function A.

看起来有点混乱是不?这边只要记住一点: __proto__ 是原型,prototype是函数默认的一个属性,它指向一个对象,这个对象的constructor属性指向函数本身.

function与object

首先看一个例子

function A(name){
this.name = name;
this.getName = function(){
console.log(this.name);
} var b = 'test';
console.log(b);
} var a = new A('testa');
A('TESTA');

当执行 var a = new A('testa'); 得到的a是这样的:

而我们执行 A('TESTA'); 相当于:

//window.name = 'TESTA'(由于非strict模式下,this默认指向window)
//window.getName = function(){console.log(this.name);}

我们的函数A既可以直接执行,又可以new一下返回一个对象.function和object到底是什么关系,new的时候发生了什么?

new到底发生了什么

还是我们上面的问题,当我们执行 var a = new A('testa') 到底发生了什么.MDN上是这么说的

对于 var o = new Foo();

//JavaScript 实际上执行的是:
var o = new Object();
o.[[Prototype]] = Foo.prototype;
Foo.call(o);

这样大概就明白了,当我们执行 new A('testa') 的时候

JS会这样做

  1. var o = new Object();
  2. o. __proto__ = A.prototype;//这里还记得之那个function里面的默认的属性么?
  3. A.call(o)//由于这里this是指向o,可以把什么this.name/getName绑定到o上.
  4. 把这个o返回给a;//完成var a = new A()的过程.

这里注意下,上面所谓的第4步其实是一个简化的说法.真正的过程是在第3步之后,如果发现A返回是一个Object类型(非primitive类型,即非string,boolean,number,null,undefined类型就是Object类型),则直接返回A的返回值,否则把第1步new的Object返回出去.(默认情况下,JS中函数默认返回值是undefined)举个例子

function A(name){
this.name = name;
this.getName = function(){
console.log(this.name);
} var b = 'test';
console.log(b); return {};
} var a = new A('testa');//{}

这里我们把A函数的返回值设置为一个Object类型,则这个时候执行new A返回的就是A函数的返回值{}.如果我们把A的返回值设置为return [];那么我们在new A的时候也相应的得到一个空数组.

用 stackoverflow 上一个人的回答来总结下就是:

In JavaScript, most functions are both callable and instantiable: they have both a [[Call]] and [[Construct]] internal methods.

在JS中,绝大多数的函数都是既可以调用也可以实例化的.我们既可以直接执行函数得到函数的返回值.也可以通过new操作符得到一个对象.

原文地址:http://warjiang.github.io/devcat/2016/05/12/JS中new到底发生了什么/

JS中new到底发生了什么的更多相关文章

  1. js 中this到底指向哪里?

    其实js的this指向很简单.我们记住下面3种情况. this 指向的是浏览器中的window.代码如下: function fn(){ this.name='yangkun'; this.age=2 ...

  2. js中‘0’到底是 true 还是 false

    if ('0') alert("'0' is true");  if ('0' == false) alert("'0' is false");结果是,两次都 ...

  3. JS 中new一个对象发生了什么事

    今天看到一个360的前端面试题: function A(){}function B(a){  this.a=a;}function C(a){  if(a){    this.a=a;   }}A.p ...

  4. JS中this到底指哪个对象

    忘了原作者是谁了   自己也添加了一些东西  勉强可以观看一下 元素就不写了   可以自己添一下试试 先看这段代码 target.onclick = function(){ console.log(t ...

  5. js中new到底做了什么?如何重写new?

    new 构造函数()执行顺序1.在堆中开辟对象内存空间, 记为obj2.在obj 中添加__proto__属性并指向 构造函数.prototype3.将构造函数中的this 指向obj4.执行构造函数 ...

  6. JS中this到底指向谁?

    关于this的指向,是一个令人很头疼的问题.但是,你运气好,碰到了我.老夫这儿有本祖传秘籍,看懂这个,妈妈再也不用担心你的this指向不对啦! 归根结底,this指向就一句话:谁最终调用函数,this ...

  7. js中new到底做了什么?

    1.创建一个新的obj; 2.让obj_proto_=Func.prototype; 3.Func.call(obj);

  8. Js new到底发生了什么

    在Js中,我们使用了new关键字来进行实例化 那么在这个new的过程中到底发生了什么? 关于构造函数的return 正常来讲构造函数中是不用写return语句的,因为它会默认返回新创建的对象. 但是, ...

  9. js中this和回调方法循环-我们到底能走多远系列(35)

    我们到底能走多远系列(35) 扯淡: 13年最后一个月了,你们在13年初的计划实现了吗?还来得及吗? 请加油~ 主题: 最近一直在写js,遇到了几个问题,可能初入门的时候都会遇到吧,总结下. 例子: ...

随机推荐

  1. asp.net webForm登录授权

    HttpCookie cookie; cookie = FormsAuthentication.GetAuthCookie(W3Account, isRemberMe); if (isRemberMe ...

  2. Bash shell的内建命令:type

    type指令是用来观察指令时来自于外部指令还是内建在bash中的指令. type  [-tpa]  name 选项与参数: :不加任何选项与参数时,type会显示出name是外部指令还是bash内建指 ...

  3. win8没有无线网络适配器问题

    1. 先关闭ssid : 命令提示符(管理员)输入 :netsh wlan set hostednetwork mde=disallow ssid 2. 再设置无线名称和密码 :netsh wlan ...

  4. 【转】Sublime Text3注册码(可用)

    补充:2015.11.05日经过测试,3个注册码都是可用的,不会用的请百度用法... 最近觉得Sublime Text3比Notepad++好使,可惜需要购买,于是网上搜了一下,屌丝的福音啊: Sub ...

  5. 浅谈c语言结构体

    对于很多非计算机专业来说,c语言课程基本上指针都不怎么讲,更别说后面的结构体了.这造成很多学生对结构体的不熟悉.这里我就浅谈一下我对结构体的认识. 结构体,就是我们自己定义出一种新的类型,定义好之后, ...

  6. Android Studio 2.2.2 发布

    Android Studio 2.2.2 发布了.包括 canary, dev, beta, and stable 这几个系列. 该版本修复了 Android Studio 2.2.1 中排名较前的b ...

  7. Spark的WorkCount的例子

    之前为了搭建scala开发spark的环境花了几天的时间,终于搞定了,具体可以参考:http://www.cnblogs.com/ljy2013/p/4964201.html   .下面就是用一个示例 ...

  8. Unity中游戏的声音管理

    using UnityEngine;using System.Collections;using System.Collections.Generic;/// <summary>/// 用 ...

  9. Beta版

    Beta版使用说明 各文件介绍:本软件是基于visual studio 2010 平台,使用C#语言开发的windows窗体游戏.该游戏共有七个界面,分别是开始界面,游戏说明界面,模式选择界面,经典模 ...

  10. PHP面试题之驼峰字符串转换成下划线样式例子

    自己在看到这个问题的时候,想到的是用ASCII码来处理,没往万能的正则上去想.好吧,下面来看看答案: 答案1: 代码如下 复制代码 $str = 'OpenAPI'; $length = mb_str ...