JavaScript初学者必看“new”

译者按: 本文简单的介绍了new, 更多的是介绍原型(prototype),值得一读。

原文:JavaScript For Beginners: the ‘new' operator

译者: Fundebug

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习

当你使用new的时候,会:

1.创建一个新的空对象;
2.将this绑定到该对象;
3.添加一个名为__proto__的新属性,并且指向构造函数的原型(prototype);
4.返回该this对象。

如果你没有特别理解,那么我们接下来用例子来详细解释。首先定义一个构造函数Student,该函数接收两个参数name和age。

function Student(name, age){
 this.name = name;
 this.age = age;
}

现在我们使用new来创建一个新的对象:

var first = new Student('John', 26);

到底发生了什么呢?

1.一个新的对象创建,我们叫它obj;
2.this绑定到obj,任何对this的引用就是对obj的引用;
3.__proto__属性被添加到obj对象。obj.__proto__会指向Student.prototype;
4.该obj对象被赋值给first变量。

我们可以通过打印测试:

console.log(first.name);
// John
console.log(first.age);
// 26

接下来深入看看__proto__是怎么回事。

原型(Prototype)

每一个JavaScript对象都有一个原型。所有的对象都从它的原型中继承对象和属性。

打开浏览器开发者控制面板(Windows: Ctrl + Shift + J)(Mac: Cmd + Option + J),输入之前定义的Student函数:

function Student(name, age) {
 this.name = name;
 this.age = age;
}

为了证实每一个对象都有原型,输入:

Student.prototype;
// Object {...}

你会看到返回了一个对象。现在我们来尝试定义一个新的对象:

var second = new Student('Jeff', 50);

根据之前的解释,second指向的对象会有一个__proto__属性,并且应该指向父亲的prototype,我们来测试一下:

second.__proto__ === Student.prototype
// true

Student.prototype.constructor会指向Student的构造函数,我们打印出来看看:

Student.prototype.constructor;
// function Student(name, age) {
// this.name = name;
// this.age = age;
// }

好像事情越来越复杂了,我们用图来形象描述一下:

Student的构造函数有一个叫.prototype的属性,该属性又有一个.constructor的属性反过来指向Student构造。它们构成了一个环。当我们使用new去创建一个新的对象,每一个对象都有.__proto__属性反过来指向Student.prototype。

这个设计对于继承来说很重要。因为原型对象被所有由该构造函数创建的对象共享。当我们添加函数和属性到原型对象中,其它所有的对象都可以使用。

在本文我们只创建了两个Student对象,如果我们创建20,000个,那么将属性和函数放到prototype而不是每一个对象将会节省非常很多的存储和计算资源。

我们来看一个例子:

Student.prototype.sayInfo = function(){
 console.log(this.name + ' is ' + this.age + ' years old');
}

我们为Student的原型添加了一个新的函数sayInfo – 所以使用Student创建的学生对象都可以访问该函数。

second.sayInfo();
// Jeff is 50 years old

创建一个新的学生对象,再次测试:

var third = new Student('Tracy', 15);
// 如果我们现在打印third, 虽然只会看到年龄和名字这两个属性,
// 仍然可以访问sayInfo函数。
third;
// Student {name: "Tracy", age: 15}
third.sayInfo();
// Tracy is 15 years old

在JavaScript中,首先查看当前对象是否拥有该属性;如果没有,看原型中是否有该属性。这个规则会一直持续,直到成功找到该属性或则到最顶层全局对象也没找到而返回失败。

继承让你平时不需要去定义toString()函数而可以直接使用。因为toString()这个函数内置在Object的原型上。每一个我们创建的对象最终都指向Object.prototype,所以可以调用toString()。当然, 我们也可以重写这个函数:

var name = {
 toString: function(){
 console.log('Not a good idea');
 }
};
name.toString();
// Not a good idea

创建的name对象首先查看是否拥有toString,如果有就不会去原型中查找。

总结

也许这些概念对你来说有点多,但是当你理解了,使用原型可以让你写出更加高效的代码。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Javascript new关键字的玄机 以及其它

    (接上)先看张对老手不新鲜但对菜鸟很有趣的图: What the heck is that? 简直是luan lun. new 抛开上面的图,先看看上篇文章留下的第二个问题,让我们在构造器的函数体内加点东西,看会发生什么. function A(){this.p = 1}var a = new A() 会得到如下结果: 为什么用new关键字构造出来的a,会获得p这个属性?new A()这行代码做了什么事情?根据上篇文章中Function的创建过程第4步,A这个对象会有一个Construct属性(

  • javascript中IE浏览器不支持NEW DATE()带参数的解决方法

    复制代码 代码如下: var date1=new Date(dateTimes[z][1]); 在火狐下 可以正常取得时间,在IE7下 却是 NaN.纠结老长时间,放弃了new date 然后再老外的论坛中找了一段段代码可以兼容所有浏览器的格式化日期代码: 复制代码 代码如下: function NewDate(str) { str = str.split('-'); var date = new Date(); date.setUTCFullYear(str[0], str[1] - 1, s

  • js中获取时间new Date()的全面介绍

    var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1970-????) myDate.getMonth(); //获取当前月份(0-11,0代表1月) myDate.getDate(); //获取当前日(1-31) myDate.getDay(); //获取当前星期X(0-6,0代表星期天) 何问起 hovertree.com myDate.getTime(); /

  • javascript new一个对象的实质

    以前这些东西自己清楚,可是却解释不出来,也没有去深究这些东西.今天在看<悟透JavaScript>的时候,看到作者的描述,"茅厕"顿开. 现摘录如下,作者说的很是清楚: 用 var anObject = new aFunction() 形式创建对象的过程实际上可以分为三步: 第一步是建立一个新对象: 第二步将该对象内置的原型对象设置为构造函数prototype引用的那个原型对象: 第三步就是将该对象作为this参数调用构造函数,完成成员设置等初始化工作.

  • Javascript new Date().valueOf()的作用与时间戳由来详解

    众所周知PHP中对时间类型数据可以直接转换为时间戳,那么在前端脚本js中,也有方法可以实现,就是valueOf() 例如,我们可以通过这段代码输出当前时间点的时间戳 复制代码 代码如下: <script type="text/javascript">  document.write(new Date().valueOf());</script> 那么何为时间戳呢? 时间戳就是从1970年1月1日0时0分0秒到当前时间点的所有秒数.1970.1.1 0:0:0 这

  • 正则(JS)re=new RegExp("^\\d*$");与re=/^\d*$/;之间区别?

    以下代码结果为:FALSE,TRUE,TRUE      请问结果中为什么第一个为FALSE?      <form   name=form1>      字符串:<input   name="t1"   value="123456">      模式:/<input   name="t2"   value="^\d*$">/      </form>      <scri

  • js中关于new Object时传参的一些细节分析

    1, 参数是一个对象,核心js对象(native ECMAScript object)或宿主对象(host object),那么将直接返回该对象. 其生成的对象构造器仍然是所传参数对象的构造器.这样造成的后果是虽然该对象是new Object,但其constructor不一定是Object. 复制代码 代码如下: function Person(){this.name='jack';} var w = new Object(window), d = new Object(document), p

  • 关于js new Date() 出现NaN 的分析

    此NaN不为NaN: 程序代码如下: 复制代码 代码如下: var date =new Date(d); if(!date || !date.getFullYear) { return; } return S.Date.format(d,'yyyy-mm-dd');//格式化函数,跟此文无关 在其他浏览器下正常,但是在ie下,程序报错 在ie调试器下,发现date 为NaN,如图: 如果是NaN,那么if判断会返回true,会 return "",但是诡异的一幕发生了, 代码说明if判

  • JavaScript中的new的使用方法与注意事项

    原文: JavaScript, We Hardly new Ya  --Douglas Crockford.    http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/ 引用 JavaScript是一门基于原型的语言,但它却拥有一个 new 操作符使得其看起来象一门经典的面对对象语言.那样也迷惑了程序员们,导致一些有问题的编程模式. 其实你永远不需要在JavaScript使用 new Object().用字面量的形式{}去

  • js之ActiveX控件使用说明 new ActiveXObject()

    什么是 ActiveX 控件? ActiveX 控件广泛用于 Internet.它们可以通过提供视频.动画内容等来增加浏览的乐趣.不过,这些程序可能出问题或者向您提供不需要的内容.在某些情况下,这些程序可被用来以您不允许的方式从计算机收集信息.破坏您的计算机上的数据.在未经您同意的情况下在您的计算机上安装软件或者允许他人远程控制您的计算机.考虑到这些风险,您应该在完全信任发行商的情况下才安装这些程序. 当 Windows 阻止 ActiveX 控件的安装时,您应该做什么? 您可能不应该安装该 A

随机推荐