菜单

JavaScript深入之new的仿实现

2018年11月15日 - JavaScript

JavaScript 深入的new的学实现

2017/05/26 · JavaScript
· new

原文出处: 冴羽   

曾离开简书,原因参见
http://www.jianshu.com/p/0f12350a6b66。

回到值功能落实

属下去我们再度来拘禁同样种植情形,假如构造函数有返值,举个例证:

function Otaku (name, age) { this.strength = 60; this.age = age; return
{ name: name, habit: ‘Games’ } } var person = new Otaku(‘Kevin’, ’18’);
console.log(person.name) // Kevin console.log(person.habit) // Games
console.log(person.strength) // undefined console.log(person.age) //
undefined

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Otaku (name, age) {
    this.strength = 60;
    this.age = age;
 
    return {
        name: name,
        habit: ‘Games’
    }
}
 
var person = new Otaku(‘Kevin’, ’18’);
 
console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // undefined
console.log(person.age) // undefined

每当是事例中,构造函数返回了一个目标,在实例 person
中只能看归来的靶子吃之属性。

以还要小心一点,在此我们是返了一个对象,假如我们只是返回一个主导项目的值也?

重新推个例:

function Otaku (name, age) { this.strength = 60; this.age = age; return
‘handsome boy’; } var person = new Otaku(‘Kevin’, ’18’);
console.log(person.name) // undefined console.log(person.habit) //
undefined console.log(person.strength) // 60 console.log(person.age) //
18

1
2
3
4
5
6
7
8
9
10
11
12
13
function Otaku (name, age) {
    this.strength = 60;
    this.age = age;
 
    return ‘handsome boy’;
}
 
var person = new Otaku(‘Kevin’, ’18’);
 
console.log(person.name) // undefined
console.log(person.habit) // undefined
console.log(person.strength) // 60
console.log(person.age) // 18

结果完全颠倒过来,这次尽管有归值,但是一定给无回来值进行拍卖。

之所以我们尚亟需看清返回的价值是免是一个目标,如果是一个靶,我们就算返回这个目标,如果没,我们欠归什么就回去什么。

重新来拘禁第二本子的代码,也是最终一本的代码:

// 第二版本的代码 function objectFactory() { var obj = new Object(),
Constructor = [].shift.call(arguments); obj.__proto__ =
Constructor.prototype; var ret = Constructor.apply(obj, arguments);
return typeof ret === ‘object’ ? ret : obj; };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 第二版的代码
function objectFactory() {
 
    var obj = new Object(),
 
    Constructor = [].shift.call(arguments);
 
    obj.__proto__ = Constructor.prototype;
 
    var ret = Constructor.apply(obj, arguments);
 
    return typeof ret === ‘object’ ? ret : obj;
 
};

就算人微言轻,但为要是发出和好之情态。

new

一如既往句话介绍 new:

new
运算符创建一个用户定义的对象类型的实例或有构造函数的放对象类型有

或是有接触难理解,我们当学 new 之前,先瞧 new 实现了什么样成效。

举个例:

// Otaku 御宅族,简称宅 function Otaku (name, age) { this.name = name;
this.age = age; this.habit = ‘Games’; } //
因为缺少锻炼的原故,身体强度为人口堪忧 Otaku.prototype.strength = 60;
Otaku.prototype.sayYourName = function () { console.log(‘I am ‘ +
this.name); } var person = new Otaku(‘Kevin’, ’18’);
console.log(person.name) // Kevin console.log(person.habit) // Games
console.log(person.strength) // 60 person.sayYourName(); // I am Kevin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Otaku 御宅族,简称宅
function Otaku (name, age) {
    this.name = name;
    this.age = age;
 
    this.habit = ‘Games’;
}
 
// 因为缺乏锻炼的缘故,身体强度让人担忧
Otaku.prototype.strength = 60;
 
Otaku.prototype.sayYourName = function () {
    console.log(‘I am ‘ + this.name);
}
 
var person = new Otaku(‘Kevin’, ’18’);
 
console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // 60
 
person.sayYourName(); // I am Kevin

于这例子中,我们得以望,实例 person 可以:

  1. 拜到 Otaku 构造函数里之习性
  2. 看到 Otaku.prototype 中的特性

对接下,我们得以品尝在法一下了。

因为 new 是着重字,所以无法像 bind
函数一样直接挂,所以我们描绘一个函数,命名吧 objectFactory,来学 new
的机能。用之时刻是如此的:

function Otaku () { …… } // 使用 new var person = new Otaku(……); // 使用
objectFactory var person = objectFactory(Otaku, ……)

1
2
3
4
5
6
7
8
function Otaku () {
    ……
}
 
// 使用 new
var person = new Otaku(……);
// 使用 objectFactory
var person = objectFactory(Otaku, ……)

章可以自家的 Github
https://github.com/mqyqingfeng/Blog
查看

深刻系列

JavaScript深入系列目录地址:https://github.com/mqyqingfeng/Blog。

JavaScript深入系列预计写十五首左右,旨在救助大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难题概念。

若出荒唐或未兢兢业业的地方,请务必与指正,十分谢谢。如果爱或具有启发,欢迎star,对作者也是平种植鞭策。

本系列:

  1. JavaScirpt 深入的起原型到原型链
  2. JavaScript
    深入之词法作用域和动态作用域
  3. JavaScript 深入之推行上下文栈
  4. JavaScript 深入的变量对象
  5. JavaScript 深入的图域链
  6. JavaScript 深入的于 ECMAScript 规范解读
    this
  7. JavaScript 深入的实践上下文
  8. JavaScript 深入之闭包
  9. JavaScript 深入之参数按值传递
  10. JavaScript
    深入之call和apply的拟实现
  11. JavaScript 深入之bind的模仿实现

    1 赞 1 收藏
    评论

图片 1

发端实现

分析:

盖 new
的结果是一个新目标,所以于法实现的下,我们也只要成立一个新对象,假而这个目标吃
obj,因为 obj 会具有 Otaku
构造函数里之习性,想想经典延续的例证,我们可以采用 Otaku.apply(obj,
arguments)来叫 obj 添加新的性质。

在 JavaScript 深入系列第一篇被,我们便称了原型与原型链,我们明白实例的
__proto__ 属性会指向构造函数的
prototype,也多亏因为起从这样的涉嫌,实例可以拜原型上的习性。

本,我们得品味着形容第一本了:

// 第一版本代码 function objectFactory() { var obj = new Object(),
Constructor = [].shift.call(arguments); obj.__proto__ =
Constructor.prototype; Constructor.apply(obj, arguments); return obj; };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 第一版代码
function objectFactory() {
 
    var obj = new Object(),
 
    Constructor = [].shift.call(arguments);
 
    obj.__proto__ = Constructor.prototype;
 
    Constructor.apply(obj, arguments);
 
    return obj;
 
};

以就等同版备受,我们:

  1. 故此new Object() 的艺术新建了一个目标 obj
  2. 取出第一只参数,就是咱们要传的构造函数。此外因为 shift
    会修改原数组,所以 arguments 会于删去第一独参数
  3. 以 obj 的原型指向构造函数,这样 obj 就好拜到构造函数原型中之性
  4. 运 apply,改变结构函数 this 的针对性到新建的目标,这样 obj
    就可以看到构造函数中的性质
  5. 返回 obj

再次多关于:

原型与原型链,可以扣押《JavaScript深入之于原型到原型链》

apply,可以看《JavaScript深入之call和apply的模拟实现》

藏延续,可以拘留《JavaScript深入之累》

复制以下的代码,到浏览器被,我们得以举行一下测试:

function Otaku (name, age) { this.name = name; this.age = age;
this.habit = ‘Games’; } Otaku.prototype.strength = 60;
Otaku.prototype.sayYourName = function () { console.log(‘I am ‘ +
this.name); } function objectFactory() { var obj = new Object(),
Constructor = [].shift.call(arguments); obj.__proto__ =
Constructor.prototype; Constructor.apply(obj, arguments); return obj; };
var person = objectFactory(Otaku, ‘Kevin’, ’18’)
console.log(person.name) // Kevin console.log(person.habit) // Games
console.log(person.strength) // 60 person.sayYourName(); // I am Kevin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function Otaku (name, age) {
    this.name = name;
    this.age = age;
 
    this.habit = ‘Games’;
}
 
Otaku.prototype.strength = 60;
 
Otaku.prototype.sayYourName = function () {
    console.log(‘I am ‘ + this.name);
}
 
function objectFactory() {
    var obj = new Object(),
    Constructor = [].shift.call(arguments);
    obj.__proto__ = Constructor.prototype;
    Constructor.apply(obj, arguments);
    return obj;
};
 
var person = objectFactory(Otaku, ‘Kevin’, ’18’)
 
console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // 60
 
person.sayYourName(); // I am Kevin

[]~( ̄▽ ̄)~**

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图