美文网首页
Call, apply 和 bind

Call, apply 和 bind

作者: _不能说的秘密i | 来源:发表于2019-11-17 20:34 被阅读0次

    Call, apply 和 bind

    • 作用: 改变调用函数的 this 指向
    let obj1 = {
        name: "obj1 name",
        showName() {
            console.log(this.name);
        },
        showMsg(...args) {
            console.log(this.name);
            console.log(args);
        }
    };
    
    let obj2 = {
        name: "obj2 name"
    };
    
    // -- call --
    obj1.showName();          // obj1 name
    obj1.showName.call(obj2); // obj2 name
    
    // -- apply --
    obj1.showMsg.apply(obj2, ['111', '222']); // obj2 ['111', '222']
    

    原型链继承

    1. 修改子类的原形对象为父类的实例对象
    2. 修改子类原型对象的构造函数为自身的构造函数(此时的构造函数已被改变为父类)
    // 人类
    function Person() {
        this.age = 10;
        this.friends = ['jack', 'tom', 'jerry'];
        this.run = function () {
            console.log("--- run ---");
        }
    }
    
    Person.prototype.say = function () {
        console.log("--- say ---");
    }
    
    
    // 学生类
    // 1. 将 Student 的原形修改为 Person 类的实例对象
    // 2. 将 Student 的原形构造函数再修复会 Student 对象
    Student.prototype = new Person();
    Student.prototype.constructor = Student;
    function Student() {
        this.name = 'jason';
    }
    
    
    const stu = new Student();
    stu.say();  // --- run ---
    stu.run();  // --- say ---
    console.log(stu.age);  // 10
    console.log(stu.name); // jason
    

    组合式继承:

    • 原型链继承的问题: 如果是对象的属性是复杂数据类型会被多个子类实例共享
    //- 问题
    const stu1 = new Student();
    const stu2 = new Student();
    
    stu1.friends = [];
    
    // 此时两个对象的 friends 属性都被同时改变了
    console.log(stu1.friends); // []
    console.log(stu2.friends); // []
    
    • 组合式继承
    // 人类
    function Person() {
        this.age = 10;
        this.friends = ['jack', 'tom', 'jerry'];
        this.run = function () {
            console.log("--- run ---");
        }
    }
    
    Person.prototype.say = function () {
        console.log("--- say ---");
    }
     
    // 学生类
    Student.prototype = new Person();
    Student.prototype.constructor = Student;
    function Student() {
        Person.call(this);
        this.name = 'jason';
    }
    
    const stu1 = new Student();
    const stu2 = new Student();
    stu1.friends = [];
    
    console.log(stu1.friends); // []
    console.log(stu2.friends); // [ 'jack', 'tom', 'jerry' ]
    

    寄生式继承

    • 组合继承的问题: 调用两次父类构造函数, 但是这些属性是重复的, 实例对象上有一份, 原型上还有一份
    • 需要一个中间构造函数
    // 父类
    function Person(age, friends) {
        this.age = age;
        this.friends = friends;
    }
    
    // 中间临时构造函数
    function Temp() { }
    Temp.prototype = Person.prototype;
    const StudentPrototype = new Temp();
    
    // 子类
    Student.prototype = StudentPrototype;
    StudentPrototype.constructor = Student;
    function Student(options) {
        const { name, age, friends } = options;
        Person.call(this, age, friends);
        this.name = name;
    }
    
    // 使用
    let stu1 = new Student({
        name: 'alex',
        age: 10,
        friends: ['tom']
    });
    let stu2 = new Student({
        name: 'jason',
        age: 10,
        friends: ['jerry']
    });
    console.log(stu1);
    console.log(stu2);
    

    多层继承

    // 动物类
    function Animal(name, age) {
        this.name = name;
        this.age = age;
    }
    Animal.prototype.eat = function() {
        console.log('吃'); 
    }
    
    Animal.prototype.run = function () {
        console.log('跑'); 
    }
    
    // 人类
    function Person (job, name, age) {
        Animal.call(this, name, age);
        this.job = job;
    }
    
    // 寄生式继承
    function Temp() {}
    Temp.prototype = Animal.prototype;
    Person.prototype = new Temp;
    Person.prototype.constructor = Person;
    
    Person.prototype.jump = function() {
        console.log('跳'); 
    }
    
    // 寄生式继承
    function Temp2 () {}
    Temp.prototype = Person.prototype;
    Student.prototype = new Temp2();
    Student.prototype.constructor = Student;
    
    function Student(options) {
        const {name, age, job, className} = options;
        Person.call(this, name, age, job);
        this.className = className;
    }
    Student.prototype.study = function () {
        console.log('学习');
    }
    const stu1 = new Student({ name: 'tom', age : 10, job: 'student', className: 'dev' });
    const stu2 = new Student({ name: 'jerry', age : 20, job: 'teacher', className: 'test' });
    console.log(stu1); 
    console.log(stu2); 
    

    相关文章

      网友评论

          本文标题:Call, apply 和 bind

          本文链接:https://www.haomeiwen.com/subject/ejlmictx.html