this_原型链_继承

问题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的指向了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容