文章目录
创建对象
New 操作符具体干了什么?
模拟工厂函数的创建过程
//工厂函数创建对象
function createHero(name, blood, weapon) {
// 1 定义一个空对象
var o = new Object();
// 2 设置构造函数的this,让this指向刚刚创建好的对象
// 3 执行构造函数中的代码
o.name = name;
o.blood = blood;
o.weapon = weapon;
o.attack = function () {
console.log(this.weapon + ' 攻击敌人');
}
// 4 返回对象
return o;
}
// 构造函数 -- 构造对象的函数
function Hero(name, blood, weapon) {
this.name = name;
this.blood = blood;
this.weapon = weapon;
this.attack = function () {
console.log(this.weapon + ' 攻击敌人');
}
}
var hero = new Hero('刘备', 100, '剑');
new 操作符具体干了什么?
面试官问:能否模拟实现JS的new操作符
继承
目的:实现代码的重用,避免重复冗余的代码。方法:把子类型中共同的成员提取到父类型中
1. 对象之间的继承:拷贝继承(for…in…循环所有属性和方法)
// 构造一个extend函数
function extend(parent, child){
// 循环parent的属性和方法
for (var key in parent){
// 如果child中已有这个key则跳过,不覆盖
if (child[key]){
continue
}
// 在child中生成key和parent对应的value
child[key] = parent[key]
}
}
var wjl = {
name:"王健林",
money:10000000,
sayName:function(){
console.log(this.name)
}
}
var wsc = {
name:"王思聪",
}
extend(wjl,wsc)
console.log(wsc)
2. 原型继承 Child.prototype = new Parent()
原型继承缺点: 无法设置子类型构造函数的参数
// 父类型
function Person() {
this.name = 'zs';
this.age = 18;
this.sex = '男';
}
// 子类型
function Student() {
this.score = 100;
}
// 将父类型对象设为子类型的原型对象,就可以在子类型的原型对象中调用父类型的属性和方法
Student.prototype = new Person();
// 子类型的原型对象构造函数要改回为子类型
Student.prototype.constructor = Student;
var s1 = new Student();
console.log(s1.constructor);
console.dir(s1);
//子类型
function Teacher() {
this.salary = 3000;
}
3. 组合继承:原型继承(继承方法)+ 借用构造函数(继承属性)
function Person (name, age){
this.name = name
this.age = age
}
Person.prototype.sayHi = function(){
console.log("Hello")
}
// 借用构造函数
function Student (name, age){
Person.call(this, name, age)
}
// 原型继承
Student.prototype = new Person() // 将父类型对象设为子类型的原型对象,就可以在子类型的原型对象中调用父类型的属性和方法
Student.prototype.constructor = Student //改了prototype之后一定要设回constructor
s1 = new Student("zs", 18)
console.log(s1)
4. 寄生组合式继承
组合继承最大的问题就是无论什么情况下,都会调用两次父类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部,导致继承了两组相同的父类型属性:一组在子类型实例对象上,一组在子类型原型对象prototype中。
寄生组合式继承只调用了一次 SuperType 构造函数,并且因此避免了在SubType.prototype 上面创建不必要的、多余的属性。其方法是创建超类型原型的一个副本,再将结果指定给子类型的原型
function inheritPrototype(superTyper, subType) {
var prototype = Object.create(superTyper.prototype) //第一步是创建超类型原型的一个副本
prototype.constructor = subType //第二步是为创建的副本添加 constructor 属性
subType.prototype = prototype //最后将新创建的对象(即副本)赋值给子类型的原型
}
function Person (age, name) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function() {
console.log("Hello")
}
function Student(name, age) {
Person.call(this, name, age)
}
inheritPrototype(Person, Student)
s1 = new Student("zs", 18)
console.log(s1)
语法笔记
1. Object.create()
Object.create()
方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
obj1.prototype = Object.create(obj2.prototype)
创建一个对象,其prototype为obj2的prototype。