js对象及new对象/函数的比较

作者:袖梨 2022-11-14

万物皆对象

在JavaScript的世界,万物皆对象。除了null和undefined,其他基本类型数字,字符串和布尔值都有对应有包装对象。对象的一个特征是你可以在它身上直接调用方法。对于数字基本类型,当试图在其身上调用toString方法会失败,但用括号括起来后再调用就不会失败了,内部实现是用相应的包装对象将基本类型转为对象。所以(1).toString()相当于new Number(1).toString()。因此,你的确可以把基本类型数字,字符串,布尔等当对象使用的,只是注意语法要得体。

同时我们注意到,JavaScript中数字是不分浮点和整形的,所有数字其实均是浮点类型,只是把小数点省略了而以,比如你看到的1可以写成1.,这也就是为什么当你试图1.toString()时会报错,所以正确的写法应该是这样:1..toString(),或者如上面所述加上括号,这里括号的作用是纠正JS解析器,不要把1后面的点当成小数点。内部实现如上面所述,是将1.用包装对象转成对象再调用方法。

使用new则是将之当做构造函数来调用,会创建一个该类的实例对象,这个对象的type是这个函数名,中间使用this.propertyname=value会对该实例对象的属性赋值,并且无论有没有return,都会返回这个对象。

而如果是直接调用就是简单执行里面的代码,不会创建实例对象,this指向的调用环境下的this对象,如果是在全局中直接调用,就是window,没有默认返回值。

想要创建类,一般用前者(构造器模式),当然也可以使用后者,例如工厂模式和寄生构造器模式。
构造器模式:

代码如下 复制代码

function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.introduce=function(){
alert("My name is "+this.name+", I am"+age+"year(s) old, I am a "+job+".");
}
}

工厂模式:

代码如下 复制代码

function createPerson(name,age,job){
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
return o;
}

寄生构造器模式:

代码如下 复制代码

function SpecialArray(){
var values=new Array();
values.push.apply(values,arguments);
values.toPipedString=function(){
return this.join("|");
};
return values;
}

后两种方法的缺点在于因为返回的还是object类型,所以不能通过instanceof来检测实际类型。


下面实例说明一下:

javascript函数能通过new操作符来调用构造器,比如new Chenqiguo()。就其定义而言,和普通的函数没有任何区别。事实上区别在于:当函数调用new操作符时,javascript为它提供了一个prototype对象;而当函数被用作构造器构建新的对象时,其内部的[[prototype]]属性就成为了被构建对象的引用

这句话是什么意思呢,我们先来看下面的代码

代码如下 复制代码

function Chenqiguo(){
alert('qiguo');
}
Chenqiguo()和new Chenqiguo()出来的效果都是一样的,都会打印qiguo这个字符串,而把代码换成如下的方式的话:
function Chenqiguo(){
alert('qiguo');
}
Chenqiguo.prototype.getName = function(){
alert('prototype qiguo');
}

我们分别用new实例化构造函数和用普通的函数执行对原型求值

代码如下 复制代码

var chenqiguo = new Chenqiguo();//打印qiguo
chenqiguo.getName(); //打印prototype name
var name = Chenqiguo(); //打印qiguo
name.getName(); //会报错, name is undefined

可以看到当我们用new 操作符创建的对象的时候能够打印原型上的值,而用常规函数的时候却不能,这样就解释了在我们当把函数当作构造函数创建新的对象的时候,其内部的prototype属性成为了被创建对象的一个引用.

抛开语言层次来观察函数和构造器的话,构造器的名称通常都使用首字母大写的形式来表表明其是一个构造函数,用小写字母的话就表示其是一个普通的函数.作为javascript的开发人员来说,应该严格区分这两种情况,如果是构造器就首字母大写,否则首字母就小写

相关文章

精彩推荐