继承

作者: candy252324 | 来源:发表于2017-02-20 17:09 被阅读0次

    1.继承有什么作用?

    继承的作用就是让一个类能够重用另一个类的方法和属性,提高代码的复用性。
    这样的话就会有一个“基类”,创建的子类将会继承基类的所有属性和方法,包括构造函数和方法的实现。这些属性和方法都是公用的,子类还可以添加基类中没有的新的私有的属性和方法,当然也可以覆盖基类中的属性和方法。

    2.有几种常见创建对象的方式? 举例说明?

    (1) 直接创建

    var obj1={
        name:"candy",
        sayName:function(){
            console.log(this.name)
        }
    }
    var obj2={
        name:"hank",
        sayName:function(){
            console.log(this.name)
        }
    }
    

    缺点:虽然对象内部都拥有相同的属性,但还是每个都要单独定义。重复造轮子。

    (2)工厂模式

    function Fun(name){
        var obj={
            name:name,
            sayName:function(){
                console.log(this.name)
            }
        }
        return obj;
    }
    var p1=Fun("candy");
    var p2=Fun("hank");
    

    解决上面的缺点,但是无法得到对象的类型。

    (3)构造函数模式

    function People(name){
         this.name=name;
         sayName:function(){
            console.log(this.name)
        }
    }
    var p1=new People("candy");
    var p2=new People("hank");
    

    缺点:每个实例对象都有sayName这个函数,而函数的功能是一样的,如果有一万个实例对象就有一万个函数,太浪费了。

    (4)原型方式

    function People(name){
        this.name=name;
    }
    People.prototype.sayName=function(){
        console.log(this.name)
    }
    var p1=new People("candy");
    var p2=new People("hank");
    

    原型方式创建对象的原则是,把所有对象使用的公共资源(sayName方法)都放在原型对象。
    缺点:所有属性都会被实例所共享,实例间对该属性的修改会相互影响。

    3.下面两种写法有什么区别?

     //写法1
    function People(name, sex){
         this.name = name;
         this.sex = sex;
         this.printName = function(){
              console.log(this.name);
         }
    }
    var p1 = new People('饥人谷', 2)
    
    //写法2
    function Person(name, sex){
         this.name = name;
         this.sex = sex;
    }
    Person.prototype.printName = function(){
         console.log(this.name);
    }
    var p1 = new Person('若愚', 27);
    

    两种写法都创建了printName这个方法,写法1的printName方法是在构造函数Person里的,new了多少个实例对象,就会产生多少个printName函数,非常浪费。
    方法2的printName方法是在构造函数Person的原型对象上的,给所有的实例对象共享。

    4.Object.create 有什么作用?兼容性如何?如何使用?

    语法:Object.create(proto, [ propertiesObject ])
    该方法用于创建一个拥有指定原型和若干个指定属性的对象(ES5)。可用于实现类似继承的功能。

    • proto:一个对象,作为新创建对象的原型。如果 proto 参数不是 null 或一个对象值,则抛出一个 TypeError 异常。
    • propertiesObject:可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符。该参数对象不能是 undefined,另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。

    兼容性:IE9+,Chrome5+,Firefox 4.0+,Opear 11.60+,Safari 5

    function Person(name){
         this.name = name;
    }
    Person.prototype.printName = function(){
         console.log(this.name);
    }
    function Man(name,sex){
         Person.call(this,name)
         this.sex=sex;
    }
    

    不使用Object.create()实现继承

            Man.prototype=new Person();
            var m1=new Man("candy","girl");
            m1.printName();   //candy
            console.log(m1 instanceof Man);   //true
            console.log(m1.__proto__==Man.prototype)  //true
            console.log(m1.constructor==Person)  //true
    

    使用Object.create()实现继承

            m2=Object.create(Person.prototype,{name:{value:"hank"},age:{value:25}})
            m2.printName();  //hank
            console.log(m2 instanceof Person);  //true
            console.log(m2.__proto__==Person.prototype) //true
            console.log(m2.constructor==Person)  //true  
    

    原型对象(Person.prototype)上的属性被实例所共享,实例间对该属性的修改会相互影响。

    console.log(Person.prototype.printName)   // function (){console.log(this.name);}
    m2.__proto__.printName=function(){
         console.log(2222);
    }
    Person.prototype.printName()   //2222
    m1.printName()   //2222
    

    obj1=Object.create(obj)是浅拷贝

    var obj={name:"candy",age:20}
    var obj1=Object.create(obj);
    obj1.name="hank";
    console.log(obj.name )    //candy
    

    5.hasOwnProperty 有什么作用? 如何使用?

    hasOwnProperty()方法用来判断某个对象是否含有指定的私有属性.该方法会忽略从原型链上继承到的属性。

    function Person(name){
         this.name = name;
    }
    Person.prototype.printName = function(){
         console.log(this.name);
    }
    function Man(name,sex){
         Person.call(this,name)
         this.sex=sex;
    }
    Man.prototype=new Person();
    var m1=new Man("candy","girl");
    m1.hasOwnProperty("name");     //true
    m1.hasOwnProperty("printName")    //false
    

    6.实现Object.create的 polyfill,如:(ps: 写个 函数create,实现 Object.create 的功能)

    function create(obj){
         if (typeof obj === "object" ) {
                function fn(){};
                fn.prototype =  obj;
                var newObj = new fn();
                fn.prototype =  null;
        }
        return newObj;
    }
    var a={name:1};
    var b=create(a);
    console.log(b.name);   //1
    

    7.如下代码中call的作用是什么?

    function Person(name, sex){
        this.name = name;
        this.sex = sex;
    }
    function Male(name, sex, age){
        Person.call(this, name, sex);    //这里的 call 有什么作用
        this.age = age;
    }
    

    在当前作用域下(即Male作用域下)执行Person函数,相当于直接写this.name=name;, this.sex=sex

    8.补全代码,实现继承

    function Person(name, sex){
        this.name=name;
        this.sex=sex;
    }
    
    Person.prototype.getName = function(){
        console.log(this.name);
    };    
    
    function Male(name, sex, age){
       Person.call(this,name,sex)
       this.age=age;
    }
    
    Male.prototype=new Person();
    Male.prototype.getAge = function(){
       console.log(this.age);
    };
    
    var ruoyu = new Male('若愚', '男', 27);
    ruoyu.getName();   //"若愚"
    ruoyu.getAge();     //27
    

    代码

    Dialog弹窗

    相关文章

      网友评论

          本文标题:继承

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