this 相關問題
問題1: apply、call 有什么作用,什么區別
call
apply
,調用一個函數,傳入函數執行上下文及參數
fn.call(context, param1, param2...)
fn.apply(context, paramArray)
語法很簡單,第一個參數都是希望設置的this
對象,不同之處在于call
方法接收參數列表,而apply
接收參數數組
問題2: 以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()
輸出: 因為函數內部this指向john這個對象
問題3: 下面代碼輸出什么,為什么
func()
function func() {
alert(this)
}
輸出:this指代window對象
問題4:下面代碼輸出什么
document.addEventListener('click', function(e){
console.log(this);
setTimeout(function(){
console.log(this);
}, 200);
}, false);
輸出:第一個this指向document,setTimeout中的this指向window。
問題5:下面代碼輸出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)
輸出:通過函數call
,使得傳入到func
的this
值為john
問題6: 以下代碼有什么問題,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
存在的問題:
$btn.on
函數內部的this
指代$btn
,因此無法找到showMsg
函數。更改如下:
var module= {
bind: function(){
var _this=this;
$btn.on('click', function(){
console.log(this) //this指什么
_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();
關聯如下:
問題8: 上例中,對對象 p可以這樣調用 p.toString()。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈。
toString
是從Object.prototype
中找到的。當調用p.toString()
時,p
會檢查自身是否有這個函數,如果有則直接調用,如果沒有,則從p.__proto__
中查找,如果還沒有找到,則從原型對象.__proto__
中尋找。原型鏈:
其基本思想是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。簡單回顧一下構造函數、原型和實例的關系:每個構造函數都有一個原型對象,原型對象都有一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。那么,假如我們讓原型對象等于另一個類型的實例,結果會怎么樣呢?顯然,此時的原型對象將包含一個指向另一個原型的指針,相應地,另一個原型中也包含著一個指向另一個構造函數的指針。假如另一個原型又是另一個類型的實例,那么上述關系依然成立,如此層層遞進,就構成了實例與原型的鏈條。這就是所謂原型鏈的基本概念。
問題9:對String做擴展,實現如下方式獲取字符串中頻率最高的字符
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因為d 出現了5次
代碼:
String.prototype.getMostOften=function () {
var strArr=[],
maxTimes=0,
times=0,
maxChar="",
_this=this;
for(var i=0;i<this.length;i++){
if($.inArray(this[i],strArr)<0){
strArr.push(this[i]);
}
}
strArr.forEach(function (e,i,array) {
var reg=new RegExp(array[i],"g");
times=_this.match(reg).length;
if(times>maxTimes){
maxTimes=times;
maxChar=array[i];
}
})
return maxChar;
}
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因為d 出現了5次
問題10: instanceOf有什么作用?內部邏輯是如何實現的?
obj instanceof func
判斷一個對象是否為給定引用類型的實例。內部邏輯是判斷該對象的原型鏈上是否存在func.prototype。
function isinstanceof(obj,func){
var oldObj=obj.__proto__;
do{
if(oldObj === func.prototype){
return true;
}else{
oldObj=oldObj.__proto__;
}
}
while(oldObj);
return 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);
方法1中每創建一個People
實例都會創建一個printName
函數。而方法2中所有實例共享printName
函數,從而節省資源。
問題13: Object.create 有什么作用?兼容性如何?
Object.create()
方法創建一個擁有指定原型和若干個指定屬性的對象。
objA=Object.create(objB.prototype)
會使得objA.__proto__ = objB.prototype
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.printName = function(){
console.log(this.name);
};
function Male(age){
this.age = age;
}
Male.prototype=Object.create(Person.prototype);
Male.prototype.printAge = function(){
console.log(this.age);
};
上述代碼會使得Male.prototype.__proto =Person.prototype
。
問題14: hasOwnProperty有什么作用? 如何使用?
hasOwnPerperty
可以判斷?個對象是否包含?定義屬性而不是原型鏈上的屬性。
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;
}
function inherit(superType, subType){
var _prototype = Object.create(superType.prototype);
_prototype.constructor = subType;
subType.prototype = _prototype;
}
inherit(Person, Male);
// 在繼承函數之后寫??的?法,否則會被覆蓋
Male.prototype.printAge = function(){
console.log(this.age);
};
var m = new Male('Byron', 'm', 26);
m.hasOwnProperty('name'); // true
m.hasOwnProperty('printName'); // false
Male.prototype.hasOwnProperty('printAge'); // true
問題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;
}
使得Male
的實例擁有Person
的屬性,從而不必再為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;
}
function inherit(superType,subType) {
subType.prototype=Object.create(superType.prototype);
subType.prototype.constructor=subType;
}
inherit(Person,Male);
Male.prototype.getAge = function(){
console.log(this.age);
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();