摘要:也就是说,构造函数内部,指的是一个新生成的空对象,所有针对的操作,都会发生在这个空对象上。上面代码中,构造函数的语句,返回的是一个新对象。
一、创建对象
1.构造函数
var Vehicle = function () {
this.price = 1000;
};
var v = new Vehicle();
v.price // 1000
new命令本身就可以执行构造函数,所以后面的构造函数可以带括号,也可以不带括号。下面两行代码是等价的,但是为了表示这里是函数调用,推荐使用括号。
// 推荐的写法
var v = new Vehicle();
// 不推荐的写法
var v = new Vehicle
一个很自然的问题是,如果忘了使用new命令,直接调用构造函数会发生什么事?
这种情况下,构造函数就变成了普通函数,并不会生成实例对象。而且由于后面会说到的原因,this这时代表全局对象,将造成一些意想不到的结果。
var Vehicle = function (){
this.price = 1000;
};
var v = Vehicle();
v // undefined
price // 1000
上面代码中,调用Vehicle构造函数时,忘了加上new命令。结果,变量v变成了undefined,而price属性变成了全局变量。因此,应该非常小心,避免不使用new命令、直接调用构造函数
为了保证构造函数必须与new命令一起使用,一个解决办法是,构造函数内部使用严格模式,即第一行加上use strict。这样的话,一旦忘了使用new命令,直接调用构造函数就会报错。
function Fubar(foo, bar){
"use strict";
this._foo = foo;
this._bar = bar;
}
Fubar()
// TypeError: Cannot set property "_f
上面代码的Fubar为构造函数,use strict命令保证了该函数在严格模式下运行。由于严格模式中,函数内部的this不能指向全局对象,默认等于undefined,导致不加new调用会报错(JavaScript 不允许对undefined添加属性)。
2.object.create()
二、new 命令的原理
使用new命令时,它后面的函数依次执行下面的步骤。
创建一个空对象,作为将要返回的对象实例。
将这个空对象的原型,指向构造函数的prototype属性。
将这个空对象赋值给函数内部的this关键字。
开始执行构造函数内部的代码。
也就是说,构造函数内部,this指的是一个新生成的空对象,所有针对this的操作,都会发生在这个空对象上。构造函数之所以叫“构造函数”,就是说这个函数的目的,就是操作一个空对象(即this对象),将其“构造”为需要的样子
三、构造函数里return(new总是返回一个对象)
如果构造函数内部有return语句,而且return后面跟着一个对象,new命令会返回return语句指定的对象;否则,就会不管return语句,返回this对象。
var Vehicle = function () {
this.price = 1000;
return 1000;
};
(new Vehicle()) === 1000
// false
上面代码中,构造函数Vehicle的return语句返回一个数值。这时,new命令就会忽略这个return语句,返回“构造”后的this对象。
但是,如果return语句返回的是一个跟this无关的新对象,new命令会返回这个新对象,而不是this对象。这一点需要特别引起注意。
var Vehicle = function (){
this.price = 1000;
return { price: 2000 };
};
上面代码中,构造函数Vehicle的return语句,返回的是一个新对象。new命令会返回这个对象,而不是this对象
(new Vehicle()).price
// 2000
四、函数的new
另一方面,如果对普通函数(内部没有this关键字的函数)使用new命令,则会返回一个空对象。
function getMessage() {
return "this is a message";
}
var msg = new getMessage();
msg // {}
typeof msg // "object"
上面代码中,getMessage是一个普通函数,返回一个字符串。对它使用new命令,会得到一个空对象。这是因为new命令总是返回一个对象,要么是实例对象,要么是return语句指定的对象。本例中,return语句返回的是字符串,所以new命令就忽略了该语句。
五、new命令简化的内部流程
function _new(/ 构造函数 / constructor, / 构造函数参数 / params) {
// 将 arguments 对象转为数组
var args = [].slice.call(arguments);
// 取出构造函数
var constructor = args.shift();
// 创建一个空对象,继承构造函数的 prototype 属性
var context = Object.create(constructor.prototype);
// 执行构造函数
var result = constructor.apply(context, args);
// 如果返回结果是对象,就直接返回,否则返回 context 对象
return (typeof result === "object" && result != null) ? result : context;
}
// 实例
var actor = _new(Person, "张三", 28);
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/105694.html
摘要:首先定义空函数这个不用解释,然后把这个空函数的原型指向为的原型,然后再把的原型指向这个新的对象,一个完美传递最后,在把原型的构造方法定义成华丽的转身,结果如下结果还是不对,于是我又在大神的肩膀上垫了一下脚。 总是听说面向对象,类,继承,__proto__,prototype,constructor.......于是乎小整理一下。 首先说,JS里的继承是怎么弄的呢? 首先创建类(Pers...
摘要:递归函数递归函数的用法递归函数在一个函数里在调用这个函数本身。如来根本不会管师徒四人按照什么流程去取。面向对象的程序优点是解决了程序的扩展性。 递归函数 递归函数的用法: - 递归函数:在一个函数里在调用这个函数本身。 - 递归的最大深度:998 实例 找一个函数的索引位置,递归实现 l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,5...
摘要:涵义实质使用场合使用注意点避免多层避免数组处理方法中的避免回调函数中的绑定的方法参考链接涵义就是属性或方法当前所在的对象。上面代码是一个文本输入框,每当用户输入一个值,就会调用回调函数,验证这个值是否在指定范围。 涵义实质使用场合使用注意点避免多层 this避免数组处理方法中的 this避免回调函数中的 this绑定 this 的方法 Function.prototype.call...
摘要:涵义实质使用场合使用注意点避免多层避免数组处理方法中的避免回调函数中的绑定的方法参考链接涵义就是属性或方法当前所在的对象。上面代码是一个文本输入框,每当用户输入一个值,就会调用回调函数,验证这个值是否在指定范围。 涵义实质使用场合使用注意点避免多层 this避免数组处理方法中的 this避免回调函数中的 this绑定 this 的方法 Function.prototype.call...
摘要:涵义实质使用场合使用注意点避免多层避免数组处理方法中的避免回调函数中的绑定的方法参考链接涵义就是属性或方法当前所在的对象。上面代码是一个文本输入框,每当用户输入一个值,就会调用回调函数,验证这个值是否在指定范围。 涵义实质使用场合使用注意点避免多层 this避免数组处理方法中的 this避免回调函数中的 this绑定 this 的方法 Function.prototype.call...
阅读 747·2021-10-14 09:43
阅读 2071·2021-09-30 09:48
阅读 3439·2021-09-08 09:45
阅读 1088·2021-09-02 15:41
阅读 1876·2021-08-26 14:15
阅读 769·2021-08-03 14:04
阅读 2970·2019-08-30 15:56
阅读 3070·2019-08-30 15:52