2010-12-08 19 views
8
var f = function(o){ return this+":"+o+"::"+(typeof this)+":"+(typeof o) }; 
f.call("2", "2"); 
// "2:2::object:string" 

var f = function(o){ return this+":"+(typeof this)+":"+(typeof o); }; 
var x = [1,/foo/,"bar",function(){},true,[],{}]; 
for (var i=0;i<x.length;++i) console.log(f.call(x[i],x[i])); 
// "1:object:number" 
// "/foo/:object:object" 
// "bar:object:string" 
// "function() {\n}:function:function" 
// "true:object:boolean" 
// ":object:object" 
// "[object Object]:object:object" 

मुझे क्रोम, फ़ायरफ़ॉक्स और सफारी में एक ही परिणाम दिखाई देता है, इसलिए मुझे लगता है कि यह the spec प्रति है, लेकिन ... क्यों? और जहां spec में यह परिभाषित किया गया है? और क्यों नहीं कार्यों के लिए?'इस' वापसी 'ऑब्जेक्ट' टाइप क्यों करें?

+0

वाह, कभी नहीं पता था। अब मुझे आश्चर्य है कि यह भी क्यों है! – Matt

उत्तर

11

रूप ECMA-262 ECMAScript भाषा विशिष्टता 3 संस्करण (फुटनोट देखें) में परिभाषित किया गया है, उस पर the spec (धारा 15.3.4.4) आधारित है:

var result = fun.call(thisArg[, arg1[, arg2[, ...]]]); 

पैरामीटर

thisArg

मज़े के अंदर इस मान का निर्धारण करता है। यदि यह आर्ग शून्य या अपरिभाषित है, यह वैश्विक वस्तु होगी। अन्यथा, इस वस्तु (thisArg) के बराबर हो जाएगा (जो thisArg अगर thisArg अगर thisArg इसी प्रकार की एक आदिम मूल्य है पहले से ही एक वस्तु, या एक स्ट्रिंग, बूलियन, या संख्या है)। इसलिए, यह हमेशा सत्य है कि फ़ंक्शन निष्पादित होने पर यह == "ऑब्जेक्ट" टाइप करें।

विशेष रूप से अंतिम पंक्ति में ध्यान दें।

महत्वपूर्ण बात यह है कि जे एस पुरातन (string, number, boolean, null, undefined) अपरिवर्तनीय हैं, इसलिए एक समारोह उन्हें संलग्न नहीं किया जा सकता है। इसलिए call फ़ंक्शन Object में आदिम को लपेटता है ताकि फ़ंक्शन संलग्न किया जा सके।

उदाहरण के लिए:

काम नहीं करता:

var test = "string"; 
//the next 2 lines are invalid, as `test` is a primitive 
test.someFun = function() { alert(this); }; 
test.someFun(); 

काम करता है:

var test = "string"; 
//wrap test up to give it a mutable wrapper 
var temp = Object(test); 
temp.someFun = function() { alert(this); }; 
temp.someFun(); 

(फुटनोट) - के रूप में patrick dw टिप्पणी में बताया गया है, इस ECMA-262 ECMAScript Language Specification 5th edition में जब सख्त में बदल जाएगा मोड:

धारा 15.3.4.4 से:

नोट thisArg मूल्य इस मूल्य के रूप में संशोधन के बिना पारित कर दिया है। यह संस्करण 3 से एक परिवर्तन है, जहां अपरिभाषित या शून्य है, इस ऑर्ग को को वैश्विक ऑब्जेक्ट के साथ प्रतिस्थापित किया गया है और ToObject अन्य सभी मानों पर लागू होता है और परिणाम इस मान के रूप में पारित किया जाता है।

+3

ध्यान दें कि यह ईसीएमएस्क्रिप्ट 5 के रूप में बदलता है। धारा 15.3.4.4: * नोट \t यह एआरआरजी मान इस मान के रूप में संशोधन के बिना पारित किया गया है।यह संस्करण 3 से एक परिवर्तन है, जहां एक अनिर्धारित या शून्य यह आर्ग को वैश्विक ऑब्जेक्ट के साथ प्रतिस्थापित किया गया है और ToObject को अन्य सभी मानों पर लागू किया गया है और परिणाम इस मान के रूप में पारित किया गया है। * – user113716

+0

आह हे, जो हमें सही ट्रैक पर रखता है ECMAScript-262 rev3 spec में। धारा 15.3.4.4 कहता है "यदि _thisArg_ ** शून्य ** या ** अनिर्धारित ** है, तो कहा जाता है कि फ़ंक्शन को वैश्विक वस्तु को ** ** ** के रूप में पारित किया जाता है। अन्यथा, बुलाया गया कार्य पारित किया जाता है 'ToObject (thisArg) '** ** यह ** मूल्य के रूप में।" धारा 9.9 में 'ToObject' ऑपरेटर का वर्णन किया गया है। असल में 'कॉल' का उपयोग किसी संख्या के साथ 'नई संख्या (42)' गुजरने जैसा है, जिसके लिए 'टाइपोफ' उपज 'ऑब्जेक्ट "' है। धन्यवाद! – Phrogz

+0

@patrickdw परिवर्तन पर उत्कृष्ट समाचार, नोट के लिए धन्यवाद! – Phrogz

संबंधित मुद्दे