继承

问题

1.继承有什么作用?

  • 继承是指一个对象直接使用另一对象的属性和方法。
  • 作用:
    1.当js中的两个对象有很多的共性时,子对象的构造函数没必要重新实现父对象的共性,而可以采用继承的方式,继承父对象的属性和方法,这样子对象在拥有父对象的特性的同时,也可以对自己的特性进行扩充,实现了代码的复用,程序的优化,js中通过原型链来实现继承。
    2.用纯js做一些复杂的工具或框架系统就要用到了,比如webgis、或者js框架如jquery、ext等,继承可以减少代码量,有利于维护代码

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

  • 字面量形式:var obj={a:1,b:2}

  • 构造函数方式,先创建一个构造函数(有参数),通过new创建
    function people(name,age){
    this.name=name;
    this.age=age;
    this.sayName=function(){
    console.log('my name is',this.name)
    }
    }
    var p1=new people('mike',20)

  • 工厂模式 ,通过return得到不同的对象返回值,但是得不到对象的类型
    function createPeople(name,sex){
    var obj={
    name:name,
    sex:sex,
    sayName:function(){
    console.log('my name is',this.name)
    }
    }
    return obj
    }
    var p1=createPeople('nick','man')
    var p2=createPeople('mary','woman')

  • 原型方式 ,在构造函数内部定义对象的属性,在构造函数的原型对象中定义公共的方法,节省代码,优化内存

     function createPeople(name,sex){
     this.name=name;
     this.sex=sex;
     }
     createPeople.prototype.sayName=function(){
     console.log('my name is '+this.name)
     }
     var p1= new createPeople('nick','man')
     p1.sayName()
     var p2= new createPeople('mary','woman')
     p2.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);
  • 方法1,使用的是构造函数的模式,这种方法创建对象的属性和方法都是在构造函数的内部创建并执行,无法实现继承和扩展,每次创建都要重新执行函数,重复创造消耗空间和性能,
  • 方法2,使用的原型方式,将对象共有的方法printName在构造函数的原型中定义,这样每次创建对象时,printName方法不会重复创建,当创造对象时,直接调用原型对象中保存的方法,实现了继承,便于扩展,有利于代码简洁,性能的优化

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

  • Object.create() 方法创建一个拥有指定原型和若干个指定属性的对象。

  • 兼容性:IE9+,Chrome5+,Firfox4.0+,Opera11.60+,Safari5+

  • 使用Object.create()来实现类式继承,语法:Object.create(*proto,* [ *propertiesObject* ]),将创建的原型对象赋值到新函数的原型,实现继承
    // 构造函数
    function people(name,sex){
    this.name=name;
    this.sex=sex;
    }
    people.prototype.printName=function(){
    console.log('my name is '+this.name)
    }
    function student(name,sex,grade){
    people.call(this,name,sex)
    this.grade=grade;
    }
    //Object.create来使student继承people的方法
    function inherit(parent,child){
    var _prototype=Object.create(parent.prototype)
    _prototype.constructor=child;
    child.prototype=_prototype;
    }
    inherit(people,student)

    student.prototype.study=function(){
      console.log(this.name+'是'+this.grade+'学生')
    }
    var p1=new student('nick','man','三年级');
    p1.printName();
    p1.study();
    

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

  • hasOwnProperty()方法用来判断某个对象是否含有指定的自身属性。

  • 所有继承了 Object.prototype的对象都会从原型链上继承到 hasOwnProperty 方法,这个方法可以用来检测一个对象是否含有特定的自身属性,和 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。

  • 使用 hasOwnProperty方法判断某对象是否含有特定的自身属性
    var obj={};
    obj.name="nick";
    function test() {
    obj.newName=obj.name;
    delete obj.name;
    }

    obj.hasOwnProperty('name');//true
    test();
    obj.hasOwnProperty('name');//false
    obj.hasOwnProperty('newName');//true
    
  • hasOwnProperty 方法对待自身属性和继承属性的区别
    var obj=new Object();
    obj.name="mike";//自身属性
    obj.hasOwnProperty('name')//true
    obj.hasOwnProperty('toString')//false,继承Object的属性
    obj.hasOwnProperty('hasOwnProperty')//false,继承Object的属性

  • 如果一个对象拥有自己的 hasOwnProperty方法, 则原型链上的同名方法会被遮蔽(shadowed)
    var foo={
    hasOwnProperty:function () {
    return false
    },
    name:'nick'
    }
    foo.hasOwnProperty('name')//false,因为一直调用了obj的hasownProperty
    //解决方法,直接使用原型链的真正的hasOwnProperty
    ({}).hasOwnProperty.call(foo, 'bar'); //true,请在控制台直接操作,不然会报错
    Object.prototype.hasOwnProperty.call(foo,'name')//true

  • 遍历一个对象的所有自身属性
    var buz = {
    fog: 'stack'
    };

          for (var name in buz) {
              if (buz.hasOwnProperty(name)) {
                  alert("this is fog (" + name + ") for sure. Value: " + buz[name]);
              }
              else {
                  alert(name); // toString or something else
              }
          }
    

6.实现Object.create的 polyfill

  • 一个shim是一个库,它将一个新的API引入到一个旧的环境中,而且仅靠旧环境中已有的手段实现
  • 一个polyfill就是一个用在浏览器API上的shim.我们通常的做法是先检查当前浏览器是否支持某个API,如果不支持的话就加载对应的polyfill.然后新旧浏览器就都可以使用这个API了
    function create(obj){
    function temp(){};
    var newObj=(function(obj){
    if(typeof obj!='object'){
    throw TypeError('Object prototype may only be an Object or null')
    }
    temp.prototype=obj;
    var prot=new temp();
    temp.prototype=null;
    return prot
    })(obj)
    return newObj;
    }
    var obj={a:1,b:2}
    var obj2=create(obj)
    console.log(obj2.a)

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;
    }
  • call方法执行一个函数,传入执行期上下文和函数的参数,把this的作用域指向了person,在Male函数下执行person(name,sex),因此也继承了person的name和sex属性

8.补全代码,实现继承

    function Person(name, sex){
        this.name=name;
        this.sex=sex;
    }

    Person.prototype.getName = function(){
       return this.name
    };    

    function Male(name, sex, age){
       Person.call(this,name,sex)
       this.age=age
    }

    var _prototype=Object.create(Person.prototype);
    _prototype.constructor=Male;
    Male.prototype=_prototype;

    Male.prototype.printName=function(){
        console.log('name is '+this.name)
    }
    
    Male.prototype.getAge = function(){
        return this.age
    };

    var ruoyu = new Male('若愚', '男', 27);
    ruoyu.printName();//name is 若愚

代码题

实现如下dialog 弹窗功能, 参考效果

代码预览
效果预览 由于作业上传上去GitHub上有,班级预览项目没有?使用了jsbin预览

  • 小结:发现鼠标的拖拽效果不写data缓存数据也能实现。

你可能感兴趣的:(继承)