![](/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.