this 原型链 继承

2017-07-03  本文已影响0人  饥人谷_有点热

this 相关问题

1.apply、call 、bind有什么作用,什么区别

apply、call 、bind这三个方法都可以用来改变函数this的指向。

bind返回一个新函数,并且使函数内部的this为传入的第一个参数
示例:

this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 返回 81

var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域

// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81

callapply比较相似,在指定this的同时,可以传递参数。唯一区别在于call()方法接受的是若干个参数的列表,而apply()方法接受的是一个包含多个参数的数组。
示例:

function greet() {
  var reply = [this.person, 'Is An Awesome', this.role].join(' ');
  console.log(reply);
}

var i = {
  person: 'Douglas Crockford', role: 'Javascript Developer'
};

greet.call(i); // Douglas Crockford Is An Awesome Javascript Developer
var numbers = [5, 6, 2, 3, 7];
var max = Math.max.apply(null, numbers);
//max=7

2.以下代码输出什么?

var john = { 
  firstName: "John" 
}
function func() { 
  alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()

输出结果:弹窗 John:hi!

3. 下面代码输出什么,为什么

func() 
function func() { 
  alert(this)
}

[Object window],因为直接调用函数func(),this将会被指向window

4.下面代码输出什么

document.addEventListener('click', function(e){
    console.log(this);
    setTimeout(function(){
        console.log(this);
    }, 200);
}, false);

点击之后先输出:#document 延时200ms后再输出window

5.下面代码输出什么,why

var john = { 
  firstName: "John" 
}

function func() { 
  alert( this.firstName )
}
func.call(john)

输出 John,因为call 的第一个参数为指定this的指向,传入john相当于讲func中的this直线了john

6.以下代码有什么问题,如何修改

var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) //this指什么
      this.showMsg();
    })
  },
  
  showMsg: function(){
    console.log('饥人谷');
  }
}

当bind被调用,$btn被点击的时候,会报错showMsg() undefined。
主要原因是on的回调函数里的this被指向了被点击的元素本身,想要正常执行需要修改成

var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) //this指什么
      this.showMsg();
    }.bind(this))
  },
  
  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();

构造函数Person,他的prototype里有一个sayName方法。实例化一个Person 赋值给p,p的proto包含了Person.prototype里的方法和属性,以及constructor,constructor被指向Person,因为p是由Person这个构造函数创建的,相当于Person是p的模板。

8.上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。

image.png

9.对String做扩展,实现如下方式获取字符串中频率最高的字符

String.prototype.getMostOften=function(){
        var string = this,
            info={},
            get_obj,
            get_max;

        get_obj=(function(){
            
            var obj={};
            for(var i = 0;i<string.length;i++){
            if (obj[string[i]]) {
                obj[string[i]] = obj[string[i]] + 1;
            }else{
                obj[string[i]] =1;
            }
            }
            return obj;
        })(string);
        
        
        // console.log(obj);

        get_max=(function(){
            var max = 0;
            for(var i in get_obj){
            if(get_obj[i]>max){
                max = get_obj[i];
            }
        }
        return max;
        })();
        
        for(var i in get_obj){
            if (get_obj[i]===get_max) {
                info[i] = get_obj[i]
            }
        }
        // console.log(max);
        return info;
    }
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次

10. instanceOf有什么作用?内部逻辑是如何实现的?

instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
示例:

示例

instanceof的内部就是实现了如下内容:

s instanceof Person
//首先
s.__proto__ === Person.prototype //false

//得到结果是false,接下去再比较
s.__proto__.__proto__ ===Person.prototype //true

继承相关问题

11.继承有什么作用?

子类可以不重写父类的属性和方法,直接调用父类的属性和方法。同时可以拓展出自己的方法和属性。
举个例子:

1
上图中的 s既可以调用自己prototype中的方法,也可以调用父类中prototype中的方法。

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);

通过方法一创建的p1单独拥有一个printnName方法,而通过方法二创建的p1也可以调用printName方法 但是自己不拥有该方法,而是存在与原型链里由Person创建出来的实例公有的方法。

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

Object.create()方法使用指定的原型对象和其属性创建了一个新的对象。它接受两个参数,如果当参数只有一个的时候,它的作用和object()方法的行为是相同的。第二个参数的用法

目前支持该方法的浏览器有IE9+,Firefox4+, Safari5+,Opera12+ 和Chrome。也就是说IE 6 7 8 不支持。不过可以使用下面这个方法来hack 实现:


借用new来实现继承

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

使用hasOwnProperty()方法可以检测一个属性是存在于实例中,还是存在于原型中。

示例:

 function Person(){

    }
    Person.prototype={
        name:'Jack',
        age:22,
        sex:'male',
        sayName:function(){
            console.log(this.name)
        }
    }

    var p1 = new Person();
    var p2 = new Person();

    p1.name = 'Greg';
    console.log(p1.name);                   //Greg ---来自实例
    console.log(p1.hasOwnProperty('name')); //true


    console.log(p2.name);                  //Jack ---来自原型
    console.log(p2.hasOwnProperty('name'));//false

    delete p1.name;
    console.log(p1.name);                  //Jack ---来自原型
    console.log(p1.hasOwnProperty('name'));//false

15.如下代码中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;
}

继承Person 的属性

16.补全代码,实现继承

function Person(name, sex){
    // todo ...
}

Person.prototype.getName = function(){
    // todo ...
};    

function Male(name, sex, age){
   //todo ...
}

//todo ...
Male.prototype.getAge = function(){
    //todo ...
};

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

实现继承:

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

        Person.prototype.printName = function() {
            console.log(this.name);
        };

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

        Male.prototype =Object.create(Person.prototype);
        Male.prototype.constructor = Male;
        Male.prototype.getAge = function() {
            console.log(this.age);
        };

        var ruoyu = new Male('若愚', '男', 27);
        ruoyu.printName();
上一篇下一篇

猜你喜欢

热点阅读