鍍金池/ 問答/HTML/ 為什么等式一樣,返回結(jié)果不一樣?

為什么等式一樣,返回結(jié)果不一樣?

剛在阮一峰大神書中看到如下代碼,對于最后一個結(jié)果是 false 很疑惑。

var obj = {};
obj.hasOwnProperty('toString') // false

// 覆蓋掉繼承的 hasOwnProperty 方法
obj.hasOwnProperty = function () {
  return true;
};
obj.hasOwnProperty('toString') // true

Object.prototype.hasOwnProperty.call(obj, 'toString') // false(這里有疑惑)

自己一直都認(rèn)為

Object.prototype.hasOwnProperty.call(obj, 'toString') 
// 等價于
obj.hasOwnProperty('toString') 

然后再chrome 的console里試了下

var obj = {};
obj.hasOwnProperty('toString') === Object.prototype.hasOwnProperty.call(obj, 'toString')

// log: true

這兩種表達(dá)式是全等的呀,明明只是寫法不同。
所以阮大神的那個代碼里,最后一個到底為什么是false??

求大神解答,謝謝。

回答
編輯回答
挽歌

call方法只是調(diào)用一個方法,只不是是調(diào)用的時候把this設(shè)置成了你傳入的第一個參數(shù)。

Object.prototype.hasOwnProperty.call(obj, 'toString') 
// 怎么可能等價于?他們調(diào)用的函數(shù)是兩個完全不同的函數(shù)!
obj.hasOwnProperty('toString') 

下面這樣:
var obj = {};
obj.func = function(){
    console.log('func of obj')
}
function func(){
    console.log('func of global');
}

func.call(obj)//執(zhí)行的還是全局的func
2018年7月5日 04:36
編輯回答
胭脂淚

obj.hasOwnProperty('toString') === Object.prototype.hasOwnProperty.call(obj, 'toString')
你這么寫是相等,但是因為兩個都是false,才返回的true.

2017年6月13日 05:52
編輯回答
淚染裳

var obj = {};
obj.hasOwnProperty方法繼承于Object.prototype,用于檢查對象是否具有自己定義的屬性
obj沒有toString這個屬性,所以obj.hasOwnProperty('toString')為 false


obj.hasOwnProperty = function () {
return true;
}
這里定義了一個obj 的自有屬性 hasOwnProperty,遮蔽了obj的原型對象 Object.prototype 的 hasOwnProperty
因此obj.hasOwnProperty('toString')順著原型鏈先找到了自有屬性,所以結(jié)果為 true


Object.prototype.hasOwnProperty.call(obj, 'toString'),是用了Object.prototype上的hasOwnProperty屬性,不是用的自身屬性,所以為 false


所以obj.hasOwnProperty('toString') 和 Object.prototype.hasOwnProperty.call(obj, 'toString')
都是 false
自然是相等的。。。。

2018年7月26日 09:19
編輯回答
青瓷

因為call方法把hasOwnProperty方法定義到了prototype里,所以會返回false。

var obj = {};
obj.hasOwnProperty('toString') === Object.prototype.hasOwnProperty.call(obj, 'toString')

這個之所以返回true,是因為兩個都是object類型,而且都沒定義,值都是空。

var obj = {};
obj.hasOwnProperty('toString123') === Object.prototype.hasOwnProperty.call(obj, 'toString456')

這個也是相等的

2018年1月10日 08:58
編輯回答
不討喜

對象查找屬性是沿著原型鏈的,在查找一個屬性的時候,會首先查看對象自己有沒有這個屬性,如果沒有就會去對象的原型鏈上去查找,如果沒有就去對象的原型鏈的原型鏈查找...

hasOwnProperty是用來判斷對象自己是否含有某個屬性的函數(shù),不會去查找原型鏈,我們知道hasOwnProperty是定義在Object.prototype上的。

var obj = {};
obj.hasOwnProperty('toString')

此時obj自身不包含任何屬性和方法,所以對obj.hasOwnProperty求值的時候,會去查找原型鏈,最后在原型上找到了該方法;
因為toString不是obj自身含有的方法,是原型鏈中的方法,所以返回false

// 覆蓋掉繼承的 hasOwnProperty 方法
obj.hasOwnProperty = function () {
  return true;
};
obj.hasOwnProperty('toString')

此時obj有一個名字為hasOwnProperty的屬性,這個屬性的值是一個方法,當(dāng)對obj.hasOwnProperty求值的時候,因為obj本身含有這個屬性,所以不會去原型鏈上查找,這個函數(shù)的作用就是返回true,所以結(jié)果是true。

Object.prototype.hasOwnProperty.call(obj, 'toString')

此時你調(diào)用的是Object.prototype.hasOwnProperty這個方法,obj自身是不包含toString屬性的,所以返回false。

var obj = {};
obj.hasOwnProperty('toString') === Object.prototype.hasOwnProperty.call(obj, 'toString')

obj.hasOwnProperty('toString')的結(jié)果和Object.prototype.hasOwnProperty.call(obj, 'toString')的結(jié)果都是false,false === false的結(jié)果是true,你應(yīng)該比較兩個函數(shù),而不是函數(shù)的返回值;
另外當(dāng)你沒有在obj上定義hasOwnProperty的時候,對obj.hasOwnPeoperty求值的結(jié)果就是在原型鏈中定義的同名函數(shù),也就是Object.prototype.hasOwnProperty,所以你即使使用obj.hasOwnProperty === Object.prototype.hasOwnProperty結(jié)果仍然是true;

你需要在obj上定義hasOwnProperty之后再去判斷兩個函數(shù)是否相等,此時就不相同了。

var obj = {}
obj.hasOwnProperty = function() {return true}
obj.hasOwnProperty === Object.prototype.hasOwnProperty // false
2017年6月12日 17:20