2015-03-10 14 views
41

जब मैं another question का उत्तर दे रहा था, तो मैं एक शीर्ष-स्तर return कथन के साथ एक नोड.जेएस मॉड्यूल में आया था। उदाहरण के लिए: - return वास्तव में रह गए हैं निष्पादनमॉड्यूल स्तर वापसी कथन Node.js में क्यों काम करता है?

Trying to reach 
मानक आउटपुट में

लेकिन "dead code":

console.log("Trying to reach"); 
return; 
console.log("dead code"); 

यह without any errors और प्रिंट काम करता है।

लेकिन specification of return statements in ECMAScript 5.1 के अनुसार,

शब्दार्थ

एक ECMAScript कार्यक्रम वाक्य रचना गलत माना जाता है अगर यह एक वापसी कथन है कि एक FunctionBody के भीतर नहीं है शामिल हैं।

ऊपर दिखाए गए कार्यक्रम में return किसी भी फ़ंक्शन के भीतर नहीं है।

फिर यह क्यों नहीं फेंकता है?

उत्तर

82

टी एल; डॉ

मॉड्यूल इस तरह, एक समारोह के भीतर Node.js से लिपटे रहे हैं:

(function (exports, require, module, __filename, __dirname) { 
    // our actual module code 
}); 

तो ऊपर दिखाए गए कोड वास्तव में Node.js द्वारा, की तरह क्रियान्वित किया जाता है इस

(function (exports, require, module, __filename, __dirname) { 
    console.log("Trying to reach"); 
    return; 
    console.log("dead code"); 
}); 

यही कारण है कि कार्यक्रम प्रिंट केवल Trying to reach और छोड़ देता है console.log पालन return कथन में आईएनजी।

Internals

यह जहां हम समझते हैं कि कैसे Node.js मॉड्यूल प्रक्रियाओं की जरूरत है। जब आप अपनी .js फ़ाइल को Node.js के साथ चलाते हैं, तो यह उस मॉड्यूल के रूप में व्यवहार करता है और इसे v8 जावास्क्रिप्ट इंजन के साथ संकलित करता है।

यह runMain function साथ शुरू होता है,

// bootstrap main module. 
Module.runMain = function() { 
    // Load the main module--the command line argument. 
    Module._load(process.argv[1], null, true); 
    // Handle any nextTicks added in the first tick of the program 
    process._tickCallback(); 
}; 

Module._load समारोह में, एक new Module object is created और it is loaded

var module = new Module(filename, parent); 
... 
... 
try { 
    module.load(filename); 
    hadException = false; 

Module function's load does this,

// Given a file name, pass it to the proper extension handler. 
Module.prototype.load = function(filename) { 
    debug('load ' + JSON.stringify(filename) + 
     ' for module ' + JSON.stringify(this.id)); 

    assert(!this.loaded); 
    this.filename = filename; 
    this.paths = Module._nodeModulePaths(path.dirname(filename)); 

    var extension = path.extname(filename) || '.js'; 
    if (!Module._extensions[extension]) extension = '.js'; 
    Module._extensions[extension](this, filename); 
    this.loaded = true; 
}; 

हमारे फ़ाइल के विस्तार के बाद से js है, हम देखते हैं क्या Module._extensions.js के लिए है।यह here

// Native extension for .js 
Module._extensions['.js'] = function(module, filename) { 
    var content = fs.readFileSync(filename, 'utf8'); 
    module._compile(stripBOM(content), filename); 
}; 

module वस्तु की _compile कि समारोह और this is where the magic happens में शुरू हो जाती है, देखा जा सकता है

// Run the file contents in the correct scope or sandbox. Expose 
// the correct helper variables (require, module, exports) to 
// the file. 
// Returns exception, if any. 

यह वह जगह है जहां require समारोह, हमारे नोड मॉड्यूल के द्वारा प्रयोग किया जाता पहले बनाई गई है।

function require(path) { 
    return self.require(path); 
} 

require.resolve = function(request) { 
    return Module._resolveFilename(request, self); 
}; 

Object.defineProperty(require, 'paths', { get: function() { 
    throw new Error('require.paths is removed. Use ' + 
        'node_modules folders, or the NODE_PATH ' + 
        'environment variable instead.'); 
}}); 

require.main = process.mainModule; 

// Enable support to add extra extension types 
require.extensions = Module._extensions; 
require.registerExtension = function() { 
    throw new Error('require.registerExtension() removed. Use ' + 
        'require.extensions instead.'); 
}; 

require.cache = Module._cache; 

और फिर वहाँ कोड लपेटकर के बारे में कुछ है,

// create wrapper function 
var wrapper = Module.wrap(content); 

हम क्या Module.wrap करता है खोजने के लिए बाहर सेट, which is nothing but

Module.wrap = NativeModule.wrap; 

which is defined in src/node.js file और वह यह है कि जहां हम इस लगता है ,

NativeModule.wrap = function(script) { 
    return NativeModule.wrapper[0] + script + NativeModule.wrapper[1]; 
}; 

NativeModule.wrapper = [ 
    '(function (exports, require, module, __filename, __dirname) { ', 
    '\n});' 
]; 

यह कैसे हमारे कार्यक्रमों जादू चर के लिए उपयोग, exports, require, module, __filename और राशि है __dirname

फिर लिपटे समारोह संकलित और runInThisContext साथ here, निष्पादित किया जाता है

var compiledWrapper = runInThisContext(wrapper, { filename: filename }); 

और फिर आखिरकार, मॉड्यूल की संकलित लपेटी गई फ़ंक्शन ऑब्जेक्ट this की तरह लागू की जाती है, exports,के लिए आबादी वाले मानों के साथ, module, __filename और __dirname

var args = [self.exports, require, self, filename, dirname]; 
return compiledWrapper.apply(self.exports, args); 

इस प्रकार हमारा मॉड्यूल कार्रवाई की जाती है और Node.js द्वारा निष्पादित और यही वजह है return बयान में नाकाम रहने के बिना काम करता है।

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