javascript中关于new关键词的理解

Javascript中,实例化一个对象,会用到new关键字。

经常有人会问我,对于一个函数,什么时候该使用new关键字。

在回答这个问题之前,需要先了解清楚new的本质,在调用new Function的时候,new做了什么操作。

先看如下代码:

// 定义类 类名字是 classA
function classA(){
    this.name=1;
}
classA.prototype.show = function(){
    alert(this.name);
};
// 用new实例化
var b = new classA();
b.show();

var b = new classA();

这句中,new做了以下几件事情。
1、创建一个新的对象,这个对象的类型是object;
2、查找class的prototype上的所有方法、属性,复制一份给创建的Object
3、将构造函数classA内部的this指向创建的Object
4、创建的Object的__proto__指向class的prototype
5、执行构造函数class
6、返回新创建的对象给变量b

这个流程应该比较好理解的。这里再解释一下:
1、构造函数:我们一般把new 后面的函数称为构造函数,如new classA(),其中classA就为构造函数
2、第四点的__proto__,可能比较难理解。
每个对象都会在其内部初始化一个属性,就是__proto__,可以在chrome中的调试器里写个对象查看下。当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链的概念。

当我们调用b.show()时,首先b中没有show这个属性,于是,它就需要到它的__proto__中去找,也就是ClassA.prototype,
而我们在上面定义了ClassA.prototype.show=function(){}; 于是,就找到了这个方法。

再用下面的代码来理解

var b = {}
b.__proto__ =  ClassA.prototype
ClassA.call(b)

最后再用一句话总结:new关键字以ClassA()为模板创建了一个新的对象,它复制了ClassA构造器中的所有成员变量,同时this指向新创建的对象。

有2点需要注意:

1、如果构造函数内没有返回值,则默认是返回this(当前上下文),要不然就返回任意非原始类型值。
2、如果不用new关键字,如

var b = classA();

则classA值会返回undefined,并且this(执行上下文)是window对象。
也就是说如果你不new的话,this指的就是window全局对象了。
如果要理解这点,需要理清楚this的指向。

this的指向:

1、总的来说,this在函数内部使用,用来引用包含函数的对象,而不是函数本身。
2、当this值的宿主函数被封装在另一个函数的内部或在另一个函数的上下文中被调用时,this值将永远是对head对象的引用(即全局window对象)
3、使用new关键字调用构造函数时,this引用“即将创建的对象”

如下面代码:

// 定义类 类名字是 classA
function classA(){
    this.name=1;
}
//执行classA
classA();
//看下name是undefined还是1
name //返回1

看到这里,相信绝大多数人应该都理解了new的用法了。

new的疑惑

 

// 加不加new结果都一样 
var obj = new Function('var temp = 100;this.temp = 200;return temp + this.temp;'); 
alert(typeof(obj)); // function 
alert(obj()); // 300 
 
 
var obj = Function('var temp = 100;this.temp = 200;return temp + this.temp;'); 
alert(typeof(obj)); // function 
alert(obj()); // 300 

var d=Date(); 
alert(d); 

var reg1 = new RegExp('^hello$');  
var reg2 = RegExp('^hello$');  
reg1.test('hello'); // true  
reg2.test('hello'); // true  
console.log(typeof reg1); // object  
console.log(typeof reg2); // object  

测试发现使用或不使用new,最后返回的都是正则对象,且typeof它们都是object。下面都情况又不一样了

var str1 = new String(1);  
var str2 = String(1);  
var num1 = new Number('1');  
var num2 = Number('1');  
var bool1 = new Boolean(1);  
var bool2 = Boolean(1);  
 
alert(typeof str1); // object  
alert(typeof str2); // string  
alert(typeof num1); // object  
alert(typeof num2); // number  
alert(typeof bool1); // object  
alert(typeof bool2); // boolean  

或者

function person(name,age){ 
    this.name=name; 
    this.age=age; 

var p1=person('zhangsan',30); 
alert(p1);//undefined 
 
var p2=new person('zhangsan',30); 
alert(p2);//object 

JavaScript是一门基于原型的语言,但它却拥有一个 new 操作符使得其看起来象一门经典的面对对象语言。那样也迷惑了程序员,导致一些有问题的编程模式。其实你永远不需要在JavaScript使用 new Object()。用字面量的形式{}去取代吧。不要使用 new Array() ,而代之以字面量[]。JavaScript中的数组并不象Java中的数组那样工作的,使用类似Java的语法只会让你糊涂。不要使用 new Number, new String, 或者 new Boolean。这些的用法只会产生无用的类型封装对象。不要使用 new Function 去创建函数对象。用函数表达式更好。比如:

frames[0].onfocus = new Function("document.bgColor='antiquewhite'") ; 
应该

frames[0].onfocus = function () {document.bgColor = 'antiquewhite';}; 
当你这样写的时候

myObj = new function () {  
this.type = 'core';  
};  

你应该

myObj = {  
type: 'core'  
};  

原则很简单: 唯一应该要用到new操作符的地方就是调用一个构造器函数的时候。当调用一个构造器函数的时候,是强制要求使用new的

时间: 2024-07-30 14:38:28

javascript中关于new关键词的理解的相关文章

对JavaScript中this指针的新理解分享_javascript技巧

一直以来对this的理解只在可以用,会用,却没有去深究其本质.这次,借着<JavaScript The Good Parts>,作了一次深刻的理解.(所有调试都可以在控制台中看到,浏览器F12键) 下面我们一起来看看这个this吧. 在我们声明一个函数时,每个函数除了有定义时的parameters(形参),自身还会有额外的两个参数,一个是this,一个是arguments(实参).arguments就是函数实际接受到的参数,是一个类数组.arguments我只做个简略的介绍,重点我们放在thi

javascript中try...catch...finally的理解及使用教程

try...catch...finally的理解 以前,我一直喜欢用console.log(do some thing)去执行输出的类型和值,想马上看到弹出的信息,就会直接在浏览器alert()一下,这些是基础知识. 稍微复杂一点点,就要用到判断语句,if else进行条件判断,话说if条件else否则,这样的判断对于写程序代码的码侬已经是非常熟悉不过了. 如果你觉得这个也很简单,可能会用到混合if else条件判断语句加上try catch 来处理语句,虽然用try catch能处理任何的对象

javascript中的原型链深入理解

 要弄清楚原型链就要先弄清楚 function 类型,在javascript中没有类的概念,都是函数,所以它是一门函数式的编程语言 要弄清楚原型链就要先弄清楚 function 类型,在javascript中没有类的概念,都是函数,所以它是一门函数式的编程语言.类有一个很重要的特性,就是它可以根据它的构造函数来创建以它为模板的对象.在javascript中,函数就有2个功能    第一. 作为一般函数调用  第二. 作为它原型对象的构造函数 也就new()    我们来看一个例子   代码如下:

javascript中的原型链深入理解_基础知识

要弄清楚原型链就要先弄清楚 function 类型,在javascript中没有类的概念,都是函数,所以它是一门函数式的编程语言.类有一个很重要的特性,就是它可以根据它的构造函数来创建以它为模板的对象.在javascript中,函数就有2个功能 第一. 作为一般函数调用 第二. 作为它原型对象的构造函数 也就new() 我们来看一个例子 复制代码 代码如下: function a(){ this.name = 'a'; } 当创建一个函数,它会发生什么呢? 第一.它会创建1个函数对象 也就是a

针对JavaScript中this指向的简单理解_javascript技巧

首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然网上大部分的文章都是这样说的,虽然在很多情况下那样去理解不会出什么问题,但是实际上那样理解是不准确的,所以在你理解this的时候会有种琢磨不透的感觉),那么接下来我会深入的探讨这个问题.  为什么要学习this?如果你学过函数式编程,面向对象编程,那你肯定知道干什么用的,如果你没有学过,那么暂时可以

JavaScript中的函数重载深入理解_javascript技巧

在JavaScript中有一种特殊的数据类型---Function类型,JavaScript的每个函数都是Function类型的实例.由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定. <pre name="code" class="html">function sum(num1,num2) { return num1 +num2; } alert(sum(10,10)); //20 var other = sum; ale

关于javascript中this关键字(翻译+自我理解)_javascript技巧

下文有大概70%的内容出自http://www.quirksmode.org/js/this.html,另外30%是我自己对它的理解和感想.希望能对有需要的人一点帮助... 首先,先看一个很典型的关于this关键字题目: 复制代码 代码如下: var name = 'hong' var obj = { name: 'ru', getName: function(){ return function(){ return this.name; }; } } alert(obj.getName()()

JavaScript中各种宽高的理解和应用

下面来抛砖引玉,简单的把"js/jquery各种宽高的理解和应用"再来说一下! window相关的宽高 window是可以省略的,直接与window挂钩的宽高有如下几个! window.innerWidth window.innerHeight window.outerWidth window.outerHeight 展示如下: innerHeight又叫可视区域.支持IE9及以上浏览器. window.screen.height window.screen.width window.

谈谈JavaScript中function多重理解_javascript技巧

JavaScript 中的 function 有多重意义.它可能是一个构造器(constructor),承担起对象模板的作用: 可能是对象的方法(method),负责向对象发送消息.还可能是函数,没错是函数,和对象没有任何关系独立存在的可以被调用的函数. 由于语言设计者的妥协,在 JavaScript 加入了一些 class 相关的特性,以使 JavaScript 看起来确实象 Java,可以 "面向对象".虽然 JavaScript 添加了 new 和 this, 但却没有 clas