构造函数
- 一种特殊的函数,主要用来初始化对象,为对象成员赋初始值。总与
new一起使用,把对象中一些公共的属性和方法抽取出来,封装到函数中。
- 构造函数有两个特点:
- 函数体内使用
this关键字,代表了所要生成的对象实例。
- 生成对象时必须使用
new命令。
function Person(opt) {
this.uname = opt.uname;
this.age = opt.age;
}
Person.sex = '男';
var person = new Person({uname:'张三', age: 18});
var person1 = new Person({uname:'李四', age: 20});
person
person1
- 如果忘记使用了
new,直接调用函数的话,构造函数就变成了普通函数。但this会指向全局,相当于给window添加属性。
function Person(opt) {
this.uname = opt.uname;
this.age = opt.age;
}
var p = Person({uname:'张三', age: 20});
p
window.uname
window.age
- 构造函数使用
严格模式可以避免忘记使用new命令的情况发生,因为函数内部的this不能指向全局对象。
function Person(opt) {
'use strict';
this.uname = opt.uname;
this.age = opt.age;
}
var p = Person({ uname: '张三', age: 20 });
function Person(opt) {
if(!(this instanceof Person)){
return new Person(opt);
}
this.uname = opt.uname;
this.age = opt.age;
}
var person = Person({ uname: '张三', age: 18 });
person
new 命令原理
function fn(){
return 'Hellow World!'
}
console.log(new fn())
模拟 new 实现
function _new(constructor) {
var obj = Object.create(constructor.prototype);
var args = Array.prototype.slice.call(arguments, 1);
const res = constructor.apply(obj, args);
return (typeof(res) === 'object' && res !== null) ? res : obj;
}
function Person(option) {
this.name = option.name;
this.age = option.age;
}
var p = _new(Person, {name: '张三', age: 20});
var p2 = _new(Person, {name: '李四', age: 18})
console.log(p)
console.log(p2)
console.log(p instanceof Person)
new.target
- 函数内部使用此属性。如果当前函数是通过
new调用的,new.target指向当前当前函数,否则为undefined。
function f() {
console.log(new.target === f);
}
f()
new f()
- 使用此方法可以判断d当前函数是否是通过
new调用的。
function f() {
if (!new.target) {
throw new Error('请使用 new 命令调用!');
}
}
f()
new f()
Ojbect.create()
var person = {
name: '张三',
age: 20,
say: function(){
console.log('My name is ' + this.name);
}
}
person.say()
var person2 = Object.create(person);
console.log(person2.name)
person2.say()