JavaScript高级——面向对象、原型

创建对象

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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值