在ES5中模拟类
1、Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 var _this = Object.create(fn.prototype);这句代码的意思是fn的prototype属性内容作为新对象的原型内容。 2、apply方法会改变this的指向。原本fn函数中调用时,也就是这样fn(),this指向的是window,但是这样使用之后fn.apply(_this, args); _this指向的是上面新创建的对象,所以改变了fn中this的指向,新对象也就有拥有了fn中的属性 。可以理解为新对象继承了fn中的属性。args是参数,必须是数组的形式,name和age属性也就有了值。 3、return中是一个三元运算,res是否存在,如果存在就返回,不存在就返回_this 。
实例化对象有一个属性叫做__proto__(原型),构造函数上有一个属性叫做prototype(原型对象)。在构造函数实例化的时候,构造函数会把prototype上面的方法和属性,复制到实例化对象的__proto__上。所以实例化对象,继承了构造函数原型上的方法和属性。
一个函数只有通过new实例化之后,才叫做构造函数。
若构造函数中没有返回值或返回值是基本类型(Number、String、Boolean)的值,则返回新实例对象;若返回值是引用类型的值,则实际返回值为这个引用类型。
apply方法会改变this的指向。原本fn函数调用时,也就是fn()这种写法,this指向的是window,但是fn.apply(_this, args)这种写法 _this指向的是上面新创建的对象,所以改变了fn中this的指向,新对象也就有拥有了fn中的属性 。可以理解为新对象继承了fn中的属性。args是参数,必须是数组的形式,name和age属性也就有了值。
//当使用new关键字去调用那个函数的时候,那这个函数就会被作为构造函数去进行调用,然后它会走构造函数的一套流程去执行这么一个函数 //在这里调用构造函数的样子跟其他语言去实例化一个类的方式也很像,都是使用new关键字,所以很容易造成混淆 //推荐写class //在js中创建一个对象的方式是很多的,构造函数也是其中的一种方式 // const obj = {} // new Object(); // Object.create(); //使用new关键字调用一个函数,这个函数就会被当做构造函数进行调用 function Person(name,age){ this.name = name; this.age = age; } //如果它没有返回值就会返回出一个对象 //不妨思考一下返回的对象是怎么出现的,为什么它上面有张三跟11 const p =new Person('张三',11) console.log(p) //p.__proto__是等于Person.prototype,这也证明了第二步,把构造函数的prototype属性作为空对象的原型。 console.log(p.__proto__ == Person.prototype) //true
//当用new关键字调用函数的时候,发生了什么,为什么会获得一个新的对象 // 1.创建一个空的对象 // 2.把构造函数的prototype属性(Person.prototype) 作为空对象的原型,这样空对象就可以访问到Person.prototype上面的方法了 // 3.this赋值为这个空对象 // 4.执行函数 // 5.如果函数没有返回值,则返回this(也可以说是返回之前那个空对象) //把一个函数变成构造函数: function Constructor(fn,args){ //fn表示要作为构造函数的函数,args表示要调用fn这个构造函数时需要传递给它的一些参数 //1.创建空对象 var _this = Object.create(fn.prototype); //以fn.prototype为原型创建的一个空对象 //第一个参数表示fn函数内部的this指向的对象,第二个参数是传入fn函数的参数 //fn函数是window对象调用的,所以this指向的是window ,然后使用apply方法,改变this指向创建的Person 对象。 var res = fn.apply(_this, args); console.log(res) //输出undefined,为什么? //如果有res就返回res,如果没有就返回创建的对象 return res ? res : _this; } function Person1(name,age){ this.name = name; this.age = age; } Person1.prototype.say = function(){ console.log('我叫' + this.name); } var person = Constructor(Person1, ['李四',21]) console.log(person)