高级2 - this_原型链_继承

this相关问题

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

  • apply()call()函数都可以 指定this值和参数值的情况下调用某个函数。
  • call()apply()的作用一样,区别在于提供给原函数的参数的方式不一样
    • apply()函数只接受两个参数,提供给原函数的参数以数组或类数组对象的形式存在
    • call()接收无限个参数, 第二个参数及其后面的参数就是提供给原函数的参数。

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

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

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

func()   //  弹出window对象

function func() { 
  alert(this)
}
  • 因为在函数func()被直接调用时,this绑定到全局对象。在浏览器中,window 就是该全局对象

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

function fn0(){
    function fn(){
        console.log(this);
    }
    fn();
}

fn0();  //  输出window对象


document.addEventListener('click', function(e){
    console.log(this);   //  输出document对象
    setTimeout(function(){
        console.log(this);   //  输出window对象
    }, 200);
}, false);

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

var john = { 
  firstName: "John" 
}

function func() { 
  alert( this.firstName ) 
}
func.call(john)    //  弹出John
  • func()函数通过call()函数调用,此时this为John对象,john.firstName存在,输出"John"

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

var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) // 这里的this指的是$btn
      this.showMsg();  //  $btn没有showMsg的属性,如果调用,这里会报错
    })
  },
  
  showMsg: function(){
    console.log('饥人谷');
  }
}
  • 应该改成如下:
var module= {
  bind: function(){
    var self = this;  // 先在外部将this保存成变量,再在内部调用这个变量
    $btn.on('click', function(){
      console.log(this);
      self.showMsg(); 
    })
  },

  showMsg: function(){
    console.log('饥人谷');
  }
}

这样,再进行测试,发现成功输出饥人谷

修改之后测试.png

原型链相关问题

问题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();
  • People是一个构建函数,protoTypePeople的属性(原型),即可以通过People.protoType的方式来获取这个属性,其类型是一个对象。
  • pPeople构建的实例,它有一个属性__proto__,它的值引用了p的父类PeopleprotoType属性。
  • constructorprotoType的一个属性,其值指向函数本身,例如:People.protoType.constructor就是People本身。

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

question8.png
  • toString()实际上是Object的方法
    • 如上原型图所示:对对象p调用p.toString()时,JS先从其自身的方法中找toString()方法,没有找到;
    • 然后通过__proto__属性找其父元素PeopleprotoType属性中有没有toString()方法,依然没找到;
    • 然后再通过其父元素PeopleprotoType属性中的__proto__属性即Object.protoType继续寻找,在Object.protoType找到了toString()方法。
  • 每个对象都有一个隐藏的__proto__属性,这个属性就是对其父元素原型对象(protoType)的引用。
  • 由于原型对象本身也是对象,也有__proto__属性,它的__proto__属性又指向了其更高父元素原型对象。这样就形成了一条链,这就是原型链

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

// 答案
String.prototype.getMostOften = function(){
    var box = {},
        max = 0,
        maxKey = "";
    for (var i=0, word;i<this.length;i++) {
        word = this[i];
        if (box[word] === undefined) {
            box[word] = 1;
        } else {
            box[word] += 1;
        }
    }
    for (key in box) {
        if (box[key] > max) {
            max = box[key];
            maxKey = key;
        }
    }
    return maxKey
}



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

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

  • instanceof用来检查一个对象是不是另一个构造对象的实例。
  • 其内部逻辑是测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
  • 所以如果表达式obj instanceof Foo 返回true,则并不意味着该表达式会永远返回true,因为Foo.prototype属性的值有可能会改变,改变之后的值很有可能不存在于obj的原型链上,这时原表达式的值就会成为false

继承相关问题

问题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);
  • 第一种方法将会把printName这个方法重新定义在每个构建的对象上,这样如果构建的对象比较多,也将会有许多个printName函数,将会对性能产生影响
  • 第二种方法会把printName这个方法定义到构建函数的protoType上,这样新构建的函数将会通过原型链获取到这个方法,节约了内存
  • 推荐使用第二种方法

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

  • Object.create方法可以创建一个拥有指定原型和若干个指定属性的对象。
  • 在继承中,Object.create可以用于继承属性。
  • Object.create是在ES5中规定的,其兼容性见下图:
Object.create-compatibilty.png

问题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);    //这里的 call 有什么作用
    this.age = age;
}
  • 这里的call的作用是改变构造函数People的作用域,这样就可以让PeopleMale的作用域中执行,这样People中的一些属性赋值语句也会在Male中执行。
  • 通过这种方式就实现了属性的继承。

问题16: 补全代码,实现继承

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

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

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

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

Male.prototype.getAge = function(){
    console.log(this.age);
};

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

推荐阅读更多精彩内容