this_原型链_继承

this相关问题

问题1: apply、call 、bind有什么作用,什么区别

call() 方法调用一个函数, 其具有一个指定的this值和分别地提供的参数(参数的列表)。apply()和call() 方法类似,只有一个区别,就是call()方法接受的是若干个参数的列表,而apply()方法接受的是一个包含多个参数的数组

bind()方法创建一个新的函数,当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。

问题2: 以下代码输出什么?
var john = { 
  firstName: "John" 
}
function func() { 
  alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()   // John: hi!
问题3: 以下代码输出什么?
func() 
function func() { 
  alert(this) // window
}
问题4: 以下代码输出什么?
document.addEventListener('click', function(e){
    console.log(this); // document
    setTimeout(function(){
        console.log(this); // window
    }, 200);
}, false);
问题5: 以下代码输出什么?
var john = { 
  firstName: "John" 
}

function func() { 
  alert( this.firstName )
}
func.call(john)  // John
问题6: 以下代码输出什么?
var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) // $btn
      this.showMsg();
    })
  },
  
  showMsg: function(){
    console.log('饥人谷');
  }
}

原型链相关问题

问题7:有如下代码,解释Person、 prototype、proto、p、constructor之间的关联。
function Person(name){
    this.name = name;
}
Person.prototype.sayName = function(){
    console.log('My name is :' + this.name);
}
var p = new Person("若愚")
p.sayName();
7.png
问题8: 上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。

p.proto指向Person.prototype,Person.prototype.proto指向Object.prototype,在Object.prototype中存在toString()方法,因此p可以调用toString()方法。

8.png

原型链的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针,那么当原型对象又等于另一个类型的实例,如此层层递进,就构成了实例和原型的链条,就是原型链。

问题9:对String做扩展,实现如下方式获取字符串中频率最高的字符
        String.prototype.getMostOften = function(){
            var obj = {};
            var maxValue = 0;
            var maxKey = '';
            for (var i = 0; i < this.length; i++) {
                if (obj[this[i]]) {
                    obj[this[i]] ++
                } else {
                    obj[this[i]] = 1
                }
            }
            for(var key in obj){
                if (obj[key] > maxValue) {
                    maxValue = obj[key];
                    maxKey = key;
                }
            }
            return maxKey + ",因为" + maxKey + "出现了" + maxValue + "次"
                
        }
        var str = 'ahbbccdeddddfg';
        var ch = str.getMostOften();
        console.log(ch); //d , 因为d 出现了5次
问题10: instanceOf有什么作用?内部逻辑是如何实现的?
// 语法
object instanceof constructor

instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。MDN参考

继承相关问题

问题11:继承有什么作用?

子类可以继承父类的属性和方法,因此只需定义子类特有的属性即可,可以简化子类的描述。父类提供的方法,子类通过继承可以直接使用,可提高代码的重用性。

问题12: 下面两种写法有什么区别?
//方法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中,printName()方法在构造函数中,每次实例化,printName()方法都需要单独占用内存;
方法2中,printName()方法写在原型对象中,当Person实例化后,调用printName()时会在原型链上找到该方法,这些方法都指向Person.prototype对象中,减少了内存的占用。

问题13: Object.create 有什么作用?兼容性如何?

Object.create() 方法使用指定的原型对象和其属性创建了一个新的对象。兼容性参考MDN

问题14: hasOwnProperty有什么作用? 如何使用?

hasOwnProperty() 方法会返回一个布尔值,指示对象是否具有指定的属性作为自身(不继承)属性。该方法会忽略掉那些从原型链上继承到的属性

obj.hasOwnProperty(prop) //prop代表要检测的属性
问题15:如下代码中call的作用是什么?
function Person(name, sex){
    this.name = name;
    this.sex = sex;
}
function Male(name, sex, age){
    Person.call(this, name, sex);    //使Person内部this对象指向Male的实例对象,使Male的实例对象可以使用Person的属性。
    this.age = age;
}
// 
问题16: 补全代码,实现继承
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;
}
Male.prototype = new Person();
Male.prototype.getAge = function(){
    return this.age
};

var ruoyu = new Male('若愚', '男', 27);
ruoyu.getName();

推荐阅读更多精彩内容