new 的用法
// 定义构造函数
function Person (name) {
this.name = name;
}
Person.prototype.age = 26;
// 创建实例
var person = new Person('前端橘子君');
// 调用实例
console.log(person.name); // 前端橘子君
console.log(person.age); // 26
console.log(person); // Person {name: "前端橘子君"}
这是一个很普通的实例,他们分别调用了实例和原型上的属性。
原理
根据JavaScript高级程序设计第六章构造函数模式中所写,使用new
操作符创建实例会经过4个阶段:
- 1、创建一个新对象
- 2、将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象)
- 3、执行构造函数中的代码(为这个新对象添加属性)
- 4、返回新对象
既然知道了步骤,那么我们就可以实现了。
实现
可能第二步比较难以理解,需要了解原型和原型链知识,详情可参考:原型及原型链。
我们先不管第二步,实现一个初始版本。
/**
* 实现new操作符
* @param ctor 构造函数
* @param args 构造函数需要的参数
*/
function _new (ctor, ...args) {
// 第一步,创建新对象
var obj = {};
// 第二步,忽略
// 第三步,执行构造函数,并将构造函数的初始属性都挂载在新对象上
ctor.call(obj, ...args);
// 返回新对象
return obj;
}
// 定义构造函数
function Person (name) {
this.name = name;
}
// 向构造函数的原型添加属性
Person.prototype.age = 26;
// 调用
var person = _new(Person, '前端橘子君')
console.log(person.name); // 前端橘子君
console.log(person.age); // 26
我们可以看到,我们可以调用实例的属性name
,但是没法调用Person
原型上的属性age
,why?
因为person
不在Person
的原型链上,换句话说,person
并不是Person
的实例,验证一下。
console.log(person instanceof Person); // false
不要奇怪,我们先来看看person
和Person
的原型链
person和Person的原型链
不熟悉原型和原型链的请参考:原型及原型链,用最通俗易懂的语言教你了解什么是原型和原型链。
person
的原型链:person实例 -> Object.prototype -> null
Person
的原型链:构造函数Person -> Object.prototype -> null
我们所期望的原型链:person实例 -> 构造函数Person -> Object.prototype -> null
完整代码
既然我们知道了我们想要的原型链,通过观察,我们知道,只要将person实例
的原型链(__proto__
)指向构造函数Person
的原型不就可以了么?
obj.__proto__ = ctor.prototype
这不就是第二步需要做的操作么?放进去再试试吧。
/**
* 实现new操作符
* @param ctor 构造函数
* @param args 构造函数需要的参数
*/
function _new (ctor, ...args) {
// 第一步,创建新对象
var obj = {};
// 第二步,忽略
obj.__proto__ = ctor.prototype
// 第三步,执行构造函数,并将构造函数的初始属性都挂载在新对象上
ctor.call(obj, ...args);
// 返回新对象
return obj;
}
// 定义构造函数
function Person (name) {
this.name = name;
}
// 向构造函数的原型添加属性
Person.prototype.age = 26;
// 调用
var person = _new(Person, '前端橘子君')
console.log(person.name); // 前端橘子君
console.log(person.age); // 26
console.log(person instanceof Person); // true
更多相关文档,请见:
线上地址 【前端橘子君】
GitHub仓库【前端橘子君】
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!