美文网首页
this_原型链_继承

this_原型链_继承

作者: 向前冲冲的蜗牛 | 来源:发表于2017-10-30 00:59 被阅读0次

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

apply ,call,bind都会改变函数的执行上下文,就是改变函数的this指向。

apply和call都是不会改变原函数,但是参数不一样apply的参数是数组。

bind是会创建一个新的函数,当被调用的时候,this还是指向bind()的第一个参数。而且这个新函数再次使用call或apply时失效。
从apply,bind,call的使用可以从以下代码思路出发:

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

alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));
var age=19;
var k={
  age:18,
  f:function (){
     return this.age;
  }

}
var p={
  age:39
}

var f2=k.f.bind(p);

console.log(f2());//39,this指向的是p

console.log(f2.call(window));//39,因为bind()创建的函数的this还是指向之前bind()第一个参数p,this始终不变

console.log(f2.apply(k));//39,因为bind()创建的函数的this还是指向之前bind()第一个参数p,this始终不变

var f3=k.f.call(window);
console.log(f3());//error,因为call无法产生一个新的函数

问题2: 以下代码输出什么?

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

输出的是John
可以这么思考 john.sayHi().call(john);

问题3: 下面代码输出什么,为什么

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

输出的是window
思考:func().call(window);this 就是call函数的参数。

问题4:下面代码输出什么

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

执行结果:
console.log(this)输出的是 document
而setTimeout种输出的console.log(this)
输出是window
因为setTimeout的this无论在哪个位置指向的都是window

问题5:下面代码输出什么,why

var john = { 
  firstName: "John" 
}

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

输出的结果是:
John 因为func.call(john)中将this改为了指向john对象

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

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

问题是this.showMsg()中this的指向问题
修改如下:

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

module.showMsg();

https://jsbin.com/dazigurisi/5/edit?html,js,console,output

总结this的使用:

大部分的函数调用都将call方法省略了,而call的理解就如同一个对象调用一个方法,而this则是只call的第一个参数。
修改setTImeout或者setInterval的this用bind的方法

image.png
网址为:https://stackoverflow.com/questions/11366643/how-do-i-change-scope-of-this-in-setinterval-and-settimeout-functions
修改click的this指向用bind方法如下: image.png
网址为:https://stackoverflow.com/questions/5490448/how-do-i-pass-the-this-context-into-an-event-handler
一篇方方介绍了JS 里为什么会有 this

原型链相关问题

方方的一篇关于new 到底是干什么的
https://zhuanlan.zhihu.com/p/23987456

解释:关于new到底是干什么的,我在方方的一篇文章中找到了以下观点:

不用创建临时对象,因为 new 会帮你做(你使用「this」就可以访问到临时对象);
不用绑定原型,因为 new 会帮你做(new 为了知道原型在哪,所以指定原型的名字为 prototype);
不用 return 临时对象,因为 new 会帮你做;
不要给原型想名字了,因为 new 指定名字为 prototype。

总结下来就是new其实就是返回了一个对象,这个对象在new的过程中自动创建了一个_ _proto _ 属性,这个对象中会复制构造函数自己所拥有的内容。同时 _proto _ _这个属性会指向构造函数的原型对象。

问题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();
image.png

关系为:
p._ _ proto _ _ ==Peroson.prototype ;
Person.prototype.constructor ==Person;
p.__ proto__.constructor==Person;
Person.prototype.__ proto __ ==Object.prototype;
p. __ proto__.__ proto __ ==Object.prototype;
p. __ proto__.__ proto __ ==Person.prototype.__ proto __;
Object. __ proto __ =null;

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

image.png

toSting()是object.prototype中的
P先从proto中查找是否有toString()方法,如果没有就从p.proto.proto中查找,一直沿着原型链查找,直到object的prototype中找到toString方法

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

var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次

代码如下:

var str = 'ahbbccdeddddfg';

String.prototype.getMostOften=function()
{
  var str={};
  var key;
  for(var i=0;i<this.length;i++)
    {
      key=this[i];
      if(str[key])
        {
          str[key]++;
        }
      else
        {
          str[key]=1;
        }
    }
  var max=0,maxkey;
  for(var key in str)
    {
      if(str[key]>max)
        {
          max=str[key];
          maxkey=key;
        }
    }
  return ("出现最多的字符是:"+maxkey+","+"共出现了"+max+"次");
}
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次
image.png

问题10: instanceof有什么作用?内部逻辑是如何实现的?

instanceof操作符判断一个对象是不是某个类的实例
instanceof依据原型链上的 _ proto _属性指向了构造函数的prototype

function _instanceof(fn,fn2)
{ 
  var pointer=fn.__proto__;
   while(pointer)
   {
     if(pointer==fn2.prototype)
     {
       return true;
     }
     else
     {
       pointer=pointer.__proto__;
     }
   }
  return false;
}
var arr=[1,2];
var fn2=Object;
console.log(_instanceof(arr, Array));
console.log(_instanceof(arr, fn2));
image.png

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

继承是指获取类的属性,类的方法
作用有
1.子类通过继承了父类的属性和方法,就不需要重复代码了
2.子类可以重写和扩展父类的属性和方法,但是又不会影响父类

问题12: 下面两种写法有什么区别?

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的内部有name,sex属性和printName方法,p1的 _ _ proto _ _ 指向People的prototype对象
第二种写法是p1的内部有name,sex属性,p1的 _ _ proto_ _指向People的prototype对象,printName方法存放在Person的prototype对象中

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

object.create()创建一个新对象,并且该对象的原型指向Object.create()的第一个参数对象。

var f={a:1,b:3};
var s=Object.create(f);
console.log(s.__proto__==f);
image.png

兼容性:

凡实现ECS5标准的浏览器,都能使用,IE9以上

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

              hasOwnProperty是判断一个属性是否是对象自己所拥有的属性而不是原型对象中的。
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
    }
}

问题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;
}

call作用是让Male继承Person的name,sex属性

问题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的原型对象指向Person,使用create方法是创建一个新的对象,且新函数的原型对象与Person的原型对象相同。这样做的原因是为了防止
Male修改的时候影响父元素的原型对象。
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();
image.png

总结:对于this的思考,this就是call函数传入的第一个参数。函数调用的时候引入call思考就会很任意的明白this的指向了。

相关文章

  • this_原型链_继承

    1.apply、call 、bind有什么作用,什么区别 bind:返回一个新函数,并且使函数内部的this为传入...

  • this_原型链_继承

    this 相关问题 1: apply、call 、bind有什么作用,什么区别? 在JS中,这三者都是用来改变函数...

  • this_原型链_继承

    this 相关问题 1.apply、call 、bind有什么作用,什么区别 fn.apply(context ,...

  • this_原型链_继承

    this 相关问题 问题1: apply、call 、bind有什么作用,什么区别 在 javascript 中,...

  • this_原型链_继承

    问题1: apply、call 、bind有什么作用,什么区别 改变函数执行时的上下文,具体的就是指绑定this指...

  • this_原型链_继承

    1: apply、call 、bind有什么作用,什么区别 作用:改变函数体内 this 的指向 区别:对于 ap...

  • this_原型链_继承

    1.apply、call 、bind有什么作用,什么区别 call apply的作用:调用一个函数,传入函数执行上...

  • this_原型链_继承

    this 相关 1. apply、call 、bind有什么作用,什么区别 apply、call、bind可以改变...

  • this_原型链_继承

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

  • this_原型链_继承

    this 相关问题 问题1: apply、call 、bind有什么作用,什么区别? apply,call,bin...

网友评论

      本文标题:this_原型链_继承

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