新睿云

> 知识库 > javaScript中new的使用与模拟实现

javaScript中new的使用与模拟实现

作者/来源:新睿云小编 发布时间:2020-04-03

一、现象

new运算符可以创建构造函数的实例,使用方式如下:

function Student (name, className) {

    this.name = name;

    this.className = className;

    this.school = '人生有限学校'

    this.study = function () {

        console.log('努力学习')

    }

    var hello = 'hello'

}

Student.prototype.dayTime = 8;

Student.prototype.say = function () {

    console.log('my name is ' this.name)

}

var s = new Student('hh''高一3班');

console.log(s.name) //hh

console.log(s.school) //人生有限学校

console.log(s.dayTime) //8

s.study() //'努力学习'

s.sayYourName() //'my name is hh'

由上可见,new创建出的实例:1.是一个对象 2.可以使用构造函数内部this添加的属性和方法 3.还可以使用构造函数的原型属性和方法

如果在构造函数里面有返回值呢,那么又是怎样一种表现呢:

//返回为一个对象

function Student (name, className) {

    this.name = name;

    this.className = className;

    this.age = 17

    return {

        name: name,

        sex: '女'

    }

}

let s = new Student('小易''三年二班')

s.name //'小易'

s.className //undefined

s.age //undefined

s.sex //女

//返回基本类型

function Student (name, className) {

    this.name = name;

    this.className = className;

    this.age = 17

    return 'hello'

}

let d = new Student('小林'"三年七班")

s.name //'小林'

s.className //三年七班

s.age //17

s.sex //undefined

通过上面的例子我们可以知道:4.如果构造函数显式返回的是一个对象,那么使用的是这个被返回的对象 5.如果显式返回的是基本类型,则使用的是忽略这段return语句的、本来就要返回的对象

二、模拟实现

new是关键字,是无法直接覆盖的。我通过写一个函数newFactory,来模拟new的效果let h = newFactory(Student, '小林''三年二班')

思路分析:

通过第一段中得出的五点:

是一个对象

可以使用构造函数内部this添加的属性和方法

还可以使用构造函数的原型属性和方法

如果构造函数显式返回的是一个对象,那么使用的是这个被返回的对象

如果显式返回的是基本类型,则使用的是忽略这段return语句的、本来就要返回的对象

可以初步得到有(以let h = newFactory(Student, '小林''三年二班')为例):

是一个对象 -> 创建一个新对象var obj = {}

可以使用构造函数内部this添加的属性和方法 -> 拿到构造函数后,将obj带入构造Student.apply(obj, ['小林''三年二班'])

还可以使用构造函数的原型属性和方法 -> 即将该实例的原型指向该构造函数的原型obj.__proto__ = Student.prototype

如果构造函数显式返回的是一个对象,那么使用的是这个被返回的对象 -> 在步骤2中用变量res接受apply的返回结果var res = Student.apply(obj, ['小林''三年二班']),如果res是一个对象,则返回res

如果显式返回的是基本类型,则使用的是忽略这段return语句的、本来就要返回的对象 -> 如果是基本类型,则返回obj

将这些思路凑起来,就有了:

function newFactory() {

    // 创建一个新对象

    var obj = {}

    // 获取构造函数(参数第一位),同时arguments会因去除第一个参数后,变成参数数组即['小林', '三年二班']

    Constructor = [].shift.call(arguments)

    // 将obj对象的原型指向构造函数的原型

    obj.__proto__ = Constructor.prototype

    // 执行,对obj对象进行加工操作并获得构造函数结果

    var res = Constructor.apply(obj, arguments)

    // 如果res为对象,返回res,否则返回obj

    return typeof res === 'object' ? res : obj

}

三、总结

知道实现思路后,再自己手动实现的话就不会很难了

上面的对象初始化感觉还可以换种方式:

// old

var obj = {}

obj.__proto__ = Constructor.prototype

// new

var obj = Object.create(Constructor.prototype)

少了一句话哈哈~

热门标签
new year
在线咨询
咨询热线 400-1515-720
投诉与建议
{{item.description}}

—您的烦恼我们已经收到—

我们会将处理结果发送至您的手机

请耐心等待