2015-09-16 5 views
5

मैं जावास्क्रिप्ट सीख रहा हूँ और मैं इस टुकड़ा है, जो टाइप का पता लगाने को दर्शाता है भर में आया था:{} .toString का मतलब क्या है?

var toClass = {}.toString // Copy a reference to toString for objects into toClass variable 

alert(toClass.call([1,2])) // [object Array] 
alert(toClass.call(new Date)) // [object Date] 

मुझे समझ नहीं आता क्या खाली कर्ली कोष्ठक पहली पंक्ति में लिए कर रहे हैं, इसलिए मैं इस तरह से उन्हें हटाने के लिए:

var toClass = toString 

और कोड अभी भी काम करता है। लेकिन निम्नलिखित कोड में,

function getAge() { 
    alert(this.age); 
} 

var p1 = { 
    age:1 
}; 

var tellAge=getAge; 
tellAge.call(p1); //1 

अगर मैं var tellAge=getAgevar tellAge={}.getAge को बदलने के लिए, मैं एक त्रुटि मिलती है: संपत्ति नहीं पढ़ सकते हैं अपरिभाषित की "कहते हैं"। यह क्यों है? क्या ऐसा इसलिए है क्योंकि toString एक अंतर्निहित कार्य है?

+0

क्या अपने कोड क्या कर रहा है और यह कैसे काम करता है की लाइन सिंहावलोकन प्रति एक लाइन के लिए नीचे मेरा उत्तर की जाँच करें। –

उत्तर

7

Is it because toString is a built-in function

नहीं वास्तव में, यह दोनों Object और window क्योंकि जावास्क्रिप्ट में दोनों एक toString विधि है।


{}{}.toString में जावास्क्रिप्ट में एक नई वस्तु का प्रतिनिधित्व करता है। ऑब्जेक्ट में toString विधि है और यही वह है जिसे आप संदर्भ बना रहे हैं।

यदि आप छोड़ देते हैं {} यह window.toString के बराबर है और के रूप में भाग्य यह window वस्तु अपने आप में एक toString विधि है होगा। तो सब कुछ काम जारी है।

जब आप {}.getAge आप वस्तु है, जो अस्तित्व में नहीं है से getAge विधि प्राप्त करने के लिए दुभाषिया कह रहे हैं, tellAge बराबर undefined है, जो त्रुटि की ओर जाता है की स्थापना करना cannot read property "call" of undefined

+1

शायद यह सबसे साफ जवाब है जिसे मैंने कभी भी अपने पूरे जीवन में पढ़ा है - बस वाह! और क्या मैं जोड़ सकता हूं कि जेएस में सबकुछ एक वस्तु है? – SidOfc

+0

@ सिडनी लिब्रैंड धन्यवाद, यह एक अच्छी तारीफ है। – Jamiec

+0

और ईमानदार होने के लिए एक अच्छी तरह से योग्य व्यक्ति, यह इतना आसान है कि यह मेरे मस्तिष्क को यह सोचने में दर्द देता है कि यह कितना प्रभावी है: पी – SidOfc

1
  • {} एक नया ऑब्जेक्ट Object(1) टाइप करें।
  • toString() एक स्ट्रिंग एक वस्तु (2) का प्रतिनिधित्व करने देता है।
  • प्रकार Object का एक उद्देश्य के लिए, toString() मूल्य [object Object] लौटना चाहिए।
  • call() अलग-अलग (3) प्रदान की किसी दिए गए this मूल्य और तर्क के साथ एक विधि निष्पादित करता है।
  • किसी भी समारोह है कि स्पष्ट रूप से एक वस्तु के लिए एक विधि के रूप में निर्दिष्ट नहीं की गई परोक्ष Window वस्तु को सौंपा गया है। ऐसे फ़ंक्शन में this का उपयोग करना हमेशा Window ऑब्जेक्ट को संदर्भित करता है।

अब, चलिए आपके कोड पर वापस आएं, क्या हम ?!

var toClass = {}.toString 

यह पहले Object प्रकार का सामान्य वस्तु बनाता है। यह तो विधि toString (विधि ही है, नहीं दिया गया मान।

इसका मतलब है कि toClass एक अब एक समारोह है देता है। यह एक this मूल्य के रूप में वस्तु {} उपयोग करता है।इसलिए यदि आप toClass() चलाते हैं, तो आपको हमेशा [object Object] मान प्राप्त करना चाहिए।

अब, मुश्किल बिट आता है!

toClass.call([1,2]) 

यहाँ क्या होता है:

इस आदेश ले लो? खैर, यह toClass() पर कॉल करने के समान है, सिवाय इसके कि आपके this मान अब {} नहीं है। इसके बजाय, इसे [1,2](4) द्वारा प्रतिस्थापित किया गया है। परिणामस्वरूप आपको [object Array] मिल गया है!

toClass.call(new Date) 

यहाँ क्या होता है:

अब इस आदेश ले? खैर, वही बात, वास्तव में। यह toClass() या toClass.call([1,2]) पर कॉल करने के समान है, सिवाय इसके कि आपके this मान को Date(5) के प्रकार से प्रतिस्थापित किया गया है। परिणामस्वरूप आपको [object Date] मिल गया है!

अब, यह समारोह ले:

function getAge() { 
    alert(this.age); 
} 

यहाँ क्या होता है? खैर, यह फ़ंक्शन आपकी विधि में this मान की संपत्ति age को अलर्ट करता है। डिफ़ॉल्ट रूप से, यह गुण अज्ञात है क्योंकि this मान Window है और Window ऑब्जेक्ट में age संपत्ति नहीं है।

अब, यह कमान लेने:

var p1 = { 
    age:1 
}; 

यहाँ, आप एक वस्तु ठीक एक संपत्ति है कि पैदा करते हैं। यही कारण है कि संपत्ति age है और मान 1

अब है, इस आदेश ले:

var tellAge=getAge; 

यहाँ, आप चर tellAge को समारोह getAge आवंटित। डिफ़ॉल्ट रूप से, दोनों फ़ंक्शन एक ही this मान का उपयोग करते हैं, जो Window ऑब्जेक्ट है।

tellAge.call(p1); 

यहां क्या होता है? खैर, यह tellAge() या getAge() पर कॉल करने जैसा ही है, सिवाय इसके कि आपके this मान अब Window नहीं है। इसके बजाय, इसे p1 द्वारा प्रतिस्थापित किया गया है। परिणामस्वरूप आपको 1 मिलता है, क्योंकि ऑब्जेक्ट p1 में कोई संपत्ति age है और उस संपत्ति का मूल्य 1 है!

var tellAge={}.getAge 

क्यों कि यह एक त्रुटि उत्पन्न करता है:

अब, चलो निम्न आदेश की जांच करते हैं? आप यहां क्या करने की कोशिश कर रहे हैं, Object प्रकार का एक सामान्य वस्तु बना रहा है। हालांकि इसकी डिफ़ॉल्ट रूप से toSting विधि है (जिसे इसके प्रोटोटाइप (6) में परिभाषित किया गया है), यह getAge विधि के साथ नहीं आता है। यही कारण है कि आपको एक त्रुटि मिल रही है।

var p2 = { 
    age : 18 
}; 

var p3 = { 
    age : 25 
}; 

var FObject = { 
    getage : function() { 
     return this.age; 
    } 
}; 

var tellAge = FObject.getage; 
alert(tellAge.call(p2)); //18 
alert(tellAge.call(p3)); //25 

तो यह क्या क्या करता है:

अब निम्नलिखित कोड ले? खैर:

  • सबसे पहले आप एक वस्तु p2 नाम है, जो मूल्य के साथ एक age संपत्ति 18.
  • तो है बनाने के लिए, आप एक वस्तु p3 नाम है, जो मूल्य के साथ एक age संपत्ति 25
  • तो है बनाने , आप FObject नामक एक और ऑब्जेक्ट ऑब्जेक्ट बनाते हैं, जिसमें getage विधि है।
  • फिर, आप FObject.getage को tellAge पर विधि असाइन करें।
  • फिर, आप tellAge.call(p2) पर कॉल करें। यह tellAge() पर कॉल करने के समान है, सिवाय इसके कि आपके this मान ऑब्जेक्ट p2 द्वारा प्रतिस्थापित किया गया है। परिणामस्वरूप आपको 18 मिल गया है!
  • अंत में, आप tellAge.call(p3) पर कॉल करते हैं। यह tellAge() या tellAge.call(p2) पर कॉल करने के समान है, सिवाय इसके कि आपके this मान ऑब्जेक्ट p3 द्वारा प्रतिस्थापित किया गया है। परिणामस्वरूप आपको 25 मिल गया है!

मुझे विश्वास है कि यह अंतिम उदाहरण आपके द्वारा देखे जा रहे व्यवहार का एक अच्छा अवलोकन देता है।


संदर्भ:

  1. Object
  2. Object.prototype.toString()
  3. Function.prototype.call()
  4. Array
  5. Date
  6. Object.prototype
+0

जबकि सब सच है, मुझे यकीन नहीं है इस सवाल का कौन सा हिस्सा जवाब दे रहा है। – Jamiec

+0

@ जैमिक: मैंने बहुत सारी अतिरिक्त जानकारी जोड़ दी, जो कोड के अनुसार क्या काम करता है और यह कैसे काम करता है, प्रति पंक्ति एक लाइन अवलोकन देता है। –

0

बस यह उदाहरण आपको स्पष्ट करने के लिए बनाया गया है। Jsfiddle

var toClass = {}.toString; // type detection 

function person(age){ 
    this.age = age; 
    this.getAgePlusOne = function(){ 
     return this.age + 1; 
    }; 
} 

var you = new person(20); // create a new person object and set age propery to 20 
console.log(you); 
var yourAge = you.getAgePlusOne(); // call created person object's function getAgePlusOne() to retrieve value 
console.log(yourAge); 

console.log(toClass.call(you)); // object 
console.log(toClass.call(you.getAgePlusOne)); //function 
1

हे ... कि चीजें इस तरह के एक कम समय में जवाब देने के लिए की एक बहुत कुछ है ... लेकिन आप एक लंबा रास्ता जावास्क्रिप्ट में जाना है, लेकिन आप करने वाले हैं प्यार यह ...

1) ऑब्जेक्ट नोटेशन। आपको JSON के लिए Google होना चाहिए।

ऑब्जेक्ट नोटेशन का अर्थ है, आप जावास्क्रिप्ट से प्रासंगिक एक विशिष्ट प्रारूप का उपयोग कर डेटा को परिभाषित कर सकते हैं।

{ } in object notation means, an object... more specifically speaking, this is already an instance of an object.

तुम भी सादा जावास्क्रिप्ट में यह लिख सकता है, यह इस तरह दिखेगा:

new Object() 

2) कार्य प्रथम श्रेणी के नागरिक हैं।

ठीक है, जेएस पारिस्थितिक तंत्र में कार्य वास्तव में एक बेहद मूल्यवान संपत्ति है। इसका मतलब है कि आप मूल रूप से कुछ भी कर सकते हैं जो आप उनके साथ कल्पना करते हैं। इसमें किसी अन्य ऑब्जेक्ट को "संबंधित" फ़ंक्शन के संदर्भ की प्रतिलिपि बनाना शामिल है।

{}.toString is a function. You would normally invoke it by doing {}.toString()

You are instead, just copying the reference to the function in a variable. In this case you "store" the function in the variable "toClass"

3) प्रोटोटाइप श्रृंखला। आपको Google, अच्छी तरह से प्रोटोटाइप श्रृंखला हाहा होना चाहिए।

प्रोटोटाइप श्रृंखला, चीजों को सरल रखने के लिए वर्ग विरासत "पसंद" है। तो इसका मतलब है कि यदि कक्षा ए में एक विधि "ब्लाह" है और कक्षा बी ए का "बच्चा" वर्ग है, तो यह भी "ब्लाह" विधि होगा।

In JS world, the top of the prototype chain is "Object". And many functions are already defined in the prototype of Object. Including "toString"

4) सामान्य सापेक्षता समस्या ... यह भी कहा जाता है, कहते हैं, और लागू होते हैं।

कार्य के रूप में प्रथम श्रेणी के नागरिक हैं, वे मूल रूप से एक विशिष्ट वस्तु उदाहरण से संबंधित के बिना मौजूद हो सकते हैं।

That means, you can choose on which this context you want the function to be invoked on.

डिफ़ॉल्ट रूप से, जब आप एक काम करता है लगता है कि एक वस्तु के लिए "संलग्न" आह्वान, उस वस्तु इस कि समारोह कॉल के संदर्भ हो जाता है:

{}.toString() // This executes toString in the context of {} 

लेकिन जैसा कि मैंने कहा, आप केवल यह चुन सकते हैं कि फ़ंक्शन वास्तव में कहां निष्पादित कर रहा है। इसके लिए विधियों "कॉल" और "लागू" मौजूद हैं। अपने वातावरण में

Object.prototype.toString.call({}) // This executes toString in the context of {} 

5) वैश्विक वस्तुओं:

हमारे पिछले उदाहरण में अनुवाद किया जा सकता है।

यह आसान विषय नहीं है, क्योंकि अब जावास्क्रिप्ट न केवल ब्राउज़र पर बल्कि सर्वर पर भी चलता है ... नोडजेएस इसका एक अच्छा उदाहरण है।

मान लें कि आप एक ब्राउज़र में इस चला रहे हैं ... वहाँ एक वैश्विक वस्तु खिड़की

आप मूल रूप से अपने वैश्विक वस्तु में किसी भी समारोह कॉल कर सकते हैं कहा जाता है।

So toString is equivalent to window.toString and window is descendent of Object, it will also get the method from the Object.prototype.

अब आपका जवाब

getAge is not defined in Object.prototype, so you cannot invoke a non existing function.

+0

आपका स्वरूपण अजीब है, आपके विवरण का आधा ब्लॉक उद्धरण में है जब आप किसी को उद्धृत नहीं कर रहे हैं। – Jamiec

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