欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

新建 JS 构造函数的过程

最编程 2024-07-17 18:03:24
...

废话不多说,先撸代码。


var newFunc = function ( func ){
    //1.新建一个空对象,并将 构造函数的原型对象赋给这个空对象
    var obj = Object.creat(func.prototype);
    //2.执行构造函数,相应参数被传入,并将this的上下文指向新创建的对象obj
    var ret = func.call(obj);
    //3.如果构造函数返回了对象,就舍弃之前创建的对象obj,newObj = ret
    if(typeof ret === 'object') return ret;
    //4.反之,newObj = obj
    else return obj;
}
var foo = function(name){
    this.name = name || 'lalaBao';
}
var newObj = newFunc(foo);

造函数其实和普通函数本质上并无区别,唯一的区别有两个:

1、函数首字母大写,这个区别只是约定俗成的,便于区分。你实在要小写定义构造函数也完全没问题,所以这个区别可以忽略。

2、构造函数的调用需要用new操作符,而普通函数的调用又分很多种,但是都不会用到new操作符。

所以,构造函数和普通函数的区别就在这个new操作符里,现在让我们来好好研究一下这个new操作符。

用new操作符创建对象时发生的事情:

(1)创建一个新对象;

(2)将构造函数的作用域赋给新对象(因此this就指向了这个新对象);

(3)执行构造函数中的代码(为这个新对象添加属性和方法);

(4)返回新对象;

构建函数的问题:

每个方法都要在每个实例上重新创建一遍, 虽然构造函数解决了判断实例类型的问题,但是,说到底,还是一个对象的复制过程。跟工厂模式颇有相似之处。也就是说,当我们声明了100个person对象,那么就有100个getName方法被重新生成。

这里的每一个sayName方法实现的功能其实是一模一样的,但是由于分别属于不同的实例,就不得不一直不停的为sayName分配空间。这就是工厂模式存在的第二个麻烦。

显然这是不合理的。我们期望的是,既然都是实现同一个功能,那么能不能就让每一个实例对象都访问同一个方法?

var p1 = new Person('Ness', 20);
var p2 = new Person('Ness1', 21);
console.log(p1.sayName == p2.sayName); //false

所以才有了原型链模式

推荐阅读