![](/img/trans.png)
[英]What's the best way to define a variable within the scope of a javascript function?
[英]Best way to define a function?
我總是學會在JavaScript中定義一個函數,如下所示:
function myFunction(arg1, arg2) { ... }
但是,我剛剛閱讀了谷歌的Javascript指南 ,它提到我應該定義這樣的方法:
Foo.prototype.bar = function() { ... };
問題 :示例中的“Foo”是Object,還是名稱空間? 為什么Google示例不是以下代碼(不起作用):
prototype.bar = function() { ... };
更新 :如果它有助於了解,我的所有JavaScript都將由用戶瀏覽器調用我的Web應用程序。
你的兩個例子在功能上並不相同。 第一個示例只是定義一個函數(可能是全局函數,除非您在另一個函數中定義它)。 第二個例子擴展了構造函數的原型。 可以把它想象為向Foo
類添加方法。
除非您正在構建JavaScript庫,否則我的建議是既不使用也不使用某種命名空間系統。 創建一個充當命名空間的全局對象,通過該命名空間可以訪問所有功能。
var MyObject = {
utils: {
someUtil: function() {},
anotherUtil: function() {}
},
animation: {
// A function that animates something?
animate: function(element) {}
}
};
然后:
// Assuming jQuery, but insert whatever library here
$('.someClass').click(function() {
MyObject.animation.animate(this);
});
如果要在JavaScript中模擬類,可以將“類”定義為函數(函數本身是構造函數),然后通過prototype
屬性添加方法。
function Foo() {
// This is the constructor--initialize any properties
this.a = 5;
}
// Add methods to the newly defined "class"
Foo.prototype = {
doSomething: function() { /*...*/ },
doSomethingElse: function() { /*...*/ }
};
然后:
var bar = new Foo();
console.log(bar.a); // 5
bar.doSomething();
// etc...
我總是學會在JavaScript中定義一個函數,如下所示: function myFunction(arg1, arg2) { ... }
有兩種方法可以定義函數。 作為函數聲明
function foo(...) {
...
}
或者作為函數表達式
var foo = function() {
...
};
但是,我剛剛閱讀了谷歌的Javascript指南,它提到我應該定義這樣的方法: Foo.prototype.bar = function() { ... };
這特別與對象的方法創建有關,而不僅僅是普通的獨立函數。 假設您有基礎對象聲明:
var Foo = function() {
...
};
與任何其他賦值一樣,要將函數賦值給對象的屬性,必須使用賦值表達式。 你可以用兩種方法做到這一點。 簡潔而通用的方式(根據Google的參考建議)
Foo.prototype.bar = function() {};
或者,如果您想繼續使用定義函數的聲明形式
function bar() {
...
};
Foo.prototype.bar = bar;
這通常比必要的更冗長,但在您希望將相同方法分配給多個對象原型的情況下可能很有用。
問題:示例中的“Foo”是Object,還是名稱空間? 為什么Google示例中沒有以下代碼(不起作用): prototype.bar = function() { ... };
Foo
是一個對象。 盡管這個概念可以通過靜態對象的使用來表達,正如我在回答你的另一個問題時所表明的那樣,JavaScript中沒有名稱空間。 此外,特別是在給出的示例代碼中, Foo
可能旨在成為實例化對象,這使其無法像命名空間那樣運行。
當然它不起作用: prototype
尚未定義為對象(當然,除非您將其定義為對象)。 prototype
屬性存在於每個對象上(函數也是一個對象),這就是為什么你可以做Foo.prototype.bar = ...;
。 在這里 閱讀 更多 。
這個問題和答案是7歲 ,非常過時。 此答案包括ES5 , ES6版本的新語法,並與ES7兼容。
沒有一種“最佳”方式來定義函數。 如何定義函數取決於函數的預期用途和生命周期。
定義為帶有函數標記的語句,后跟帶有小寫camelcase的函數名稱
function functionName (arguments) {
// function body
}
優於函數表達式...
var functionName = function (arguments) {
// function body
}
...因為在執行定義行之前不會發生對函數變量的賦值。 與在執行任何代碼之前解析后立即可用的首選方法不同。
const functionName = function(arguments){/*function body*/}
var functionName = function functionName(arguments){/*function body*/}
var functionName = function functionAltName(arguments){/*function body*/}
作為帶有大寫camelcase函數名的函數語句
function MyObjectFunction (arguments) {
/*function body*/
// if this function is called with the new token
// then it exits with the equivalent return this;
}
const obj = new MyObjectFunction(foo);
一種常見的做法是通過一個沒有名稱的立即調用的函數來創建對象(因此是匿名的)
;(function (arguments) { /*function body*/ } ("argument val"))
要么
;(function(arguments){ /*function body*/ })("argument val")
注意包含;
這個功能。 這非常重要,因為打開“(”將阻止在函數上方的任何代碼上插入自動分號。
const functionResult = (function (arguments) {
/*function body*/
return functionResult;
}());
const functionResult = (function (arguments) {
/*function body*/
return functionResult;
})();
作為var
或塊范圍的const
, let
使用ES6,您應該使用箭頭函數語法而不是匿名函數表達式。
myArray.forEach((item,i) => {/*function body*/});
myArray.filter(item => !item);
setTimeout(() => {/*function body*/}, 1000);
使用對象聲明函數的簡寫語法。
var myObj = {
functionName (arguments) {/*function body*/},
}
// called
myObj.functionName("arg");
比...好
var myObj = {
functionName : function (arguments) {/*function body*/},
}
或者通過函數對象聲明
function MyObjectFunction(arguments){
this.propertyFunction = function(arguments) { /*function body*/ }
// or arrow notation is fine
this.propertyFunction = (argument) => { /*function body*/ };
}
function MyObj (arguments) {
MyObj.prototype.functionName = function(arguments) { /*function body*/ }
}
要么
function MyObj (arguments) {}
MyObj.prototype.functionName = function(arguments) { /*function body*/ }
要么
MyObj.prototype = {
functionName(arguments) { /*function body*/ }
}
在JavaScript中創建構造函數或“類”時,定義原型函數很有用。 例如,你將是new
var MyClass = function(){};
MyClass.prototype.doFoo = function(arg){ bar(arg); }
但在普通的舊圖書館功能中沒有用處,例如
function doPopup(message){ /* create popup */};
使用原型功能有幾個好處,包括但不限於
但是,同樣,這是在為可實例化的“類”創建構造函數的上下文中
HTH
它的工作原理如下:
(function(){ // create an isolated scope
// My Object we created directly
var myObject = {
a: function(x,y) {
console.log('a');
},
b: function(x,y) {
console.log('b');
this.a(x,y);
}
};
})();
(function(){ // create an isolated scope
// Create a Object by using a Class + Constructor
var myClass = function(x,y) {
console.log('myClass: constructor');
this.b(x,y);
};
myClass.prototype = {
a: function(x,y) {
console.log('myClass: a');
},
b: function(x,y) {
console.log('myClass: b');
this.a(x,y);
}
};
// Define a function that should never inherit
myClass.c = function(x,y) {
console.log('myClass: c');
this.a(x,y);
};
// Create Object from Class
var myObject = new myClass();
// Will output:
// myClass: constructor
// myClass: b
// myClass: a
// Define a function that should never inherit
myObject.d = function(x,y) {
console.log('myObject: d');
this.a(x,y);
};
// Test the world is roung
console.log(typeof myClass.c, 'should be undefined...');
console.log(typeof myClass.d, 'should be function...');
})();
(function(){ // create an isolated scope
// If you are using a framework like jQuery, you can obtain inheritance like so
// Create a Object by using a Class + Constructor
var myClass = function(x,y) {
console.log('myClass: constructor');
this.b(x,y);
};
myClass.prototype = {
a: function(x,y) {
console.log('myClass: a');
},
b: function(x,y) {
console.log('myClass: b');
this.a(x,y);
}
};
// Create new Class that inherits
var myOtherClass = function(x,y) {
console.log('myOtherClass: constructor');
this.b(x,y);
};
$.extend(myOtherClass.prototype, myClass.prototype, {
b: function(x,y) {
console.log('myOtherClass: b');
this.a(x,y);
}
});
// Create Object from Class
var myOtherObject = new myOtherClass();
// Will output:
// myOtherClass: constructor
// myOtherClass: b
// myClass: a
})();
(function(){ // create an isolated scope
// Prototypes are useful for extending existing classes for the future
// Such that you can add methods and variables to say the String class
// To obtain more functionality
String.prototype.alert = function(){
alert(this);
};
"Hello, this will be alerted.".alert();
// Will alert:
// Hello, this will be alerted.
})();
編輯:修復代碼,以便在您復制並粘貼時它將實際在您的瀏覽器中運行:-)
Foo既是Object又是命名空間。 看到這個問題 。
使用對象作為名稱空間可防止名稱沖突。 這總是一個好主意,但尤其是在您開發和/或使用共享庫時。
如果您不希望制作多個Foo對象(因此不需要面向對象的樣式),您可以在單個對象上創建函數作為方法:
var Foo = {}
Foo.bar = function() { ... }
要么
var Foo = {
bar: function() {...},
quux: function() {...}
};
然后,您只需將該函數調用為:
Foo.bar()
(這種聲明大致相當於C ++或Java中的靜態方法。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.