this 相關問題
1: apply、call 、bind有什么作用,什么區別
-
apply
- 執行一個函數,傳入函數執行時的this和上下文及參數,傳入的參數為(obj,arguments)
var test = { hello : 'hello', world : 'world', sayHello : function(person){ console.log(this.hello+' '+this.world+' from '+person) } } var obj = { hello: 'byebye', world: 'baby' } test.sayHello('baby') var arr = ['mather'] test.sayHello.call(obj,arr)
-
call
- 執行一個函數,傳入函數執行時的this和上下文及參數,傳入的參數為(obj,param0...)
var test = { hello : 'hello', world : 'world', sayHello : function(person){ console.log(this.hello+' '+this.world+' from '+person) } } var obj = { hello: 'byebye', world: 'baby' } test.sayHello('baby') //hello world from baby test.sayHello.call(obj,'mather') //byebye baby from mather
-
bind
- 返回一個新函數,并且使函數內部的this為傳入的第一個參數
var obj1 = { name: 'Byron', fn : function(){ console.log(this); } } var fn2 = obj1.fn fn2() //window var fn2 = obj1.fn.bind(obj1) console.log(fn3) fn2() //obj1
- fn2是一個變量,實際上是一個函數,?
f2
與var f2=function(){console.log(this)}
是相同的,?一般情況下,f2?打印出來的應該是使用他的對象,由于我們實在全局中直接使用,所以返回window,但是通過var fn2 = obj1.fn.bind(obj1)
將他的this為obj1
-
區別
- apply與call的主要區別為傳入參數的格式不同,apply傳入要綁定的this和一個數組,call傳入要綁定this的對象和參數,不同參數用逗號隔開
- bind與apply、call的區別在于bind是聲明函數時使用,而aplly、call在調用的時候使用
2: 以下代碼輸出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()
- 輸出
John:hi!'=
3: 下面代碼輸出什么,為什么
func()
function func() {
alert(this)
}
- 輸出
window
誰調用函數就是this就指向誰,fun()可以看成是window.func()
4:下面代碼輸出什么
document.addEventListener('click', function(e){
console.log(this);
setTimeout(function(){
console.log(this);
}, 200);
}, false);
- 輸出
document
,window
5:下面代碼輸出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)
輸出:
John
原因:使用
call()
調用func
并且將func
內部的this的值改為john
6: 以下代碼有什么問題 ,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指$btn所代表的DOM元素
this.showMsg();
})
},
showMsg: function(){
console.log('饑人谷');
}
}
出現的問題 事件監聽里面的this指向的是$btn所代表的DOM元素,而這個DOM元素?是沒有showMsg方法的
-
修改
var module= { bind: function(){ $btn.on('click', function(){ console.log(this) //this指$btn所代表的DOM元素 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 = p.__proto__
Person.prototype.constructor = Person
p.__proto__ = Person
8: 上例中,對對象 p可以這樣調用 p.toString()。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈。

.toString()
方法在Person.prototype.__proto__
中,也就是p.__proto__.__proto__
中JavaScript中通過一種鏈條的形式完成繼承,例如我們聲明一個空數組arrItem,雖然是一個空數組,但是卻可以使用一切對象的方法,在這個數組的
__proto__
中擁有數組的所有方法,但是卻沒有對象的方法,繼續向在__proto__
中查找就會找到所有對象的方法。這個逐級向上查找所經過的類似鏈條一樣的東西,我們就叫他原型鏈。
9:對String做擴展,實現如下方式獲取字符串中頻率最高的字符
var str = 'ahbbccdeddddfg';
str.__proto__.getMostOften = function (){
var obj = {}
var max=0
for(var i=0;i<str.length;i++){
if( obj.hasOwnProperty( str[i] ) ){
obj[str[i]]++
if(obj[str[i]]>max){
max = obj[str[i]]
}
}else {
obj[str[i]]=1
}
}
for(var key in obj){
if(max === obj[key]){
return key
}
}
}
var ch = str.getMostOften();
console.log(ch); //d , 因為d 出現了5次
10: instanceOf有什么作用?內部邏輯是如何實現的?
作用 判斷一個對象是不是某個類型的實例
-
內部實現
function instance(param,leixing){ while(param.__proto__){ if(param.__proto__.constructor === leixing){ return true }else { param = param.__proto__ } } 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是將
printName
方法掛載到每個實例上面,方法2是將printName
寫在People的prototype
上面,也就是對象的__proto__
里面 - 方法1的好處是每一個對象都有一個相同的獨立的方法,對象的方法怎么變都不會影響到其他對象。
- 方法1的壞處是每一個對象都要占據很多的內存
- 方法2的好處是每一個對象都使用同一個方法,每個對象只擁有自己的屬性,避免了內存的浪費
- 方法1是將
13: Object.create 有什么作用?兼容性如何?
作用 將一個類的
prototype
從clone到另外一個類上,使用時應該先克隆然后在子類上添加方法,最后在將這個類的prototype.constructor
的值設置成這個類-
兼容性
- chrome: 5
- Firefox: 4.0
- IE: 9
- Opera: 11.60
- Safari: 5
14: hasOwnProperty有什么作用? 如何使用?
-
作用
- 判斷某個是自己的還是父類的
- 判斷一個對象是否包含自定義屬性而不是原型鏈上的屬性
-
使用
function Person(name,age){ this.name = name this.age = age } Person.prototype.language = 'Chinese' var p1 = new Person('Haoran',23)
- 代碼中name,age是p1的屬性,而language是Person的每一個實例化的對象都有的屬性,如果我們使用
hasOwnProperty
判斷,結果應該是name和age返回true,language是在p1的原型鏈上面的,不是p1的屬性,應該返回false
console.log(p1.hasOwnProperty('name')) //true console.log(p1.hasOwnProperty('age')) //true console.log(p1.hasOwnProperty('language')) //false
- 代碼中name,age是p1的屬性,而language是Person的每一個實例化的對象都有的屬性,如果我們使用
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){
this.name = name
this.sex = sex
}
Person.prototype.getName = function(){
return this.name
}
Person.prototype.printName = function(){
console.log(this.name)
}
function Male(name, sex, age){
this.name = name
this.sex = sex
this.age = age
}
/*繼承的代碼*/
Male.prototype = Object.create(Person.prototype)
Male.prototype.constructor = Male
Male.prototype.getAge = function(){
return this.age
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();