我想从私有方法调用公共方法,但属性"this"指向窗口对象.
请注意我正在尝试应用模块模式.您可以在jsfiddle.net上找到一个有效的代码示例
// how can i access a public method from a private one?
// (in this example publicAlert from privateMethod)
// this refers to the window object.
$(function() {
var modulePattern = (function($)
{
var privateMethod = function()
{
appendText("called privateMethod()");
this.publicAlert();
};
var appendText = function(texToAppend)
{
var text = $('#output').text() + " | " + texToAppend;
$('#output').text(text);
};
return {
publicMethod : function()
{
appendText("called publicMethod()");
privateMethod();
},
publicAlert : function()
{
alert("publicAlert");
}
}; …Run Code Online (Sandbox Code Playgroud) 我倾向于以下列方式编写对象构造函数:
function Person(name) {
this.name = name;
}
Person.prototype.greet = function () {
alert("Hello! My name is " + this.name + ".");
};
Run Code Online (Sandbox Code Playgroud)
我注意到一些JavaScript库和框架添加了一些额外的代码,如下所示:
var Person = (function () {
function Person(name) {
this.name = name;
}
Person.prototype.greet = function () {
alert("Hello! My name is " + this.name + ".");
};
return Person;
})();
Run Code Online (Sandbox Code Playgroud)
我知道自执行匿名函数的作用和用途.我目前未能看到的是,在定义构造函数及其原型时,它提供了哪些优势或好处.
编辑#1:
我知道模块模式及其优点,并且在我的编码中经常使用它.我在沟通中的错误并不清楚我的第一个代码示例不应该在全球范围内.我总是将所有外部JavaScript文件包装在一个自执行的匿名函数中,以强制执行代码的本地范围.
例如:
;(function ( window, undefined ) {
var p = function (name) {
this.name;
};
p.prototype.greet = function () {
alert("Hello! My …Run Code Online (Sandbox Code Playgroud) javascript constructor anonymous-function function-prototypes module-pattern
我想写一个JS库并像这样处理它:
var c1 = Module.Class();
c1.init();
var c1 = Module.Class();
c2.init();
Run Code Online (Sandbox Code Playgroud)
当然,c1和c2不能共享相同的变量.我想我知道如何用对象做这个,它会是:
var Module = {
Class = {
init = function(){
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
但问题是,如果我以这种方式编写,我不能拥有多个Class实例.所以我试图用功能实现同样的功能,但我认为我做得不对.
(function() {
var Module;
window.Module = Module = {};
function Class( i ) {
//How can "this" refer to Class instead of Module?
this.initial = i;
}
Class.prototype.execute = function() {
...
}
//Public
Module.Class = Class;
})();
Run Code Online (Sandbox Code Playgroud)
如果可能的话,我没有任何线索,但我接受其他方式的建议来创建这个模块.我不知道它是否也相关,但我在这个库中使用jQuery.
我得到了模块模式的基础知识,并使用了一个闭包来允许私有成员,但是我不能完全接受为什么下面的代码会做它的作用:
var Calculator = function() {
var priv = 0;
return {
changePriv: function() { priv++;},
printPriv: function() { console.log(priv);}
}
}
var myCalc = Calculator();
myCalc.printPriv();
myCalc.changePriv();
myCalc.printPriv();
var myOtherCalc = Calculator();
myCalc.printPriv();
Run Code Online (Sandbox Code Playgroud)
控制台输出是
0
1
1
Run Code Online (Sandbox Code Playgroud)
因此,故意在new此处省略关键字,第一个调用设置myCalc为Calculator对象.它以priv值0开始,递增,然后打印出新priv值1.
但是a)为什么下一次调用Calculator()最终会返回对SAME对象的引用(由第二个'1'证明)?我知道我可以new在这里使用并避免这种情况,但不知道为什么我必须这样做.是不是这个函数使用对象文字语法来实质上创建一个新对象然后返回它?b)因为它似乎确实使用了相同的函数堆栈空间(即使是在JS中考虑它的正确方法?),为什么priv在将引用返回到同一对象之前它不会将过程中的变量清零?
编辑:修正了草率/愚蠢的错误(谢谢scessor),即使不使用new关键字,它现在也会输出一个新的/不同的计算器对象.这样就可以清除a)和b).我得到的问题是" new在模块模式构造函数的调用中是否使用是否重要.答案是,我认为无关紧要(?).(约瑟夫:见http:// jsfiddle. net/MvMvy/5 / ... instanceof运算符无论如何都无法使用模块模式.)
为清晰起见编辑 - @ Qantas94Heavy - 我理解它是什么"说"或应该做什么,我不明白的是为什么以及更重要的是它是如何工作的:
我正在阅读关于JS Module Pattern的高级教程,它给出了这个例子:
var MODULE = (function (my) {
// add capabilities...
return my;
}(MODULE || {}));
Run Code Online (Sandbox Code Playgroud)
困扰我的事情(我需要你的帮助)是最后一句话:
(MODULE || {}));
Run Code Online (Sandbox Code Playgroud)
我无法理解这背后的语法规则,这使得它成为可能.在搜索关键字,"JavaScript模块语法"和"模块模式短手"之后,我发现我仍然不太了解这背后的基础.
有人请解释或指出我正确的方向,以获得更深入的了解吗?
真诚的,gggi
如何从JavaScript模块模式中的私有函数中调用公共函数?
例如,在以下代码中,
var myModule = (function() {
var private1 = function(){
// How to call public1() here?
// this.public1() won't work
}
return {
public1: function(){ /* do something */}
}
})();
Run Code Online (Sandbox Code Playgroud)
虽然这些解决方案有效,但从OOP的角度来看,它们并不令人满意.为了说明我的意思,让我们用这些解决方案中的每个解决方案对雪人进行具体实现,并将它们与简单的对象文字进行比较.
雪人1:保存对返回对象的引用
var snowman1 = (function(){
var _sayHello = function(){
console.log("Hello, my name is " + public.name());
};
var public = {
name: function(){ return "Olaf"},
greet: function(){
_sayHello();
}
};
return public;
})()
Run Code Online (Sandbox Code Playgroud)
雪人2:保存对公共功能的引用
var snowman2 …Run Code Online (Sandbox Code Playgroud) 首先是一段历史,我们有一个由许多javascript文件组成的引擎,这些文件本质上是模块.尽管在指定的命名空间下,这些模块返回分配给全局范围的单个类.
引擎本身用于显示电子教学内容,每个不同的电子教学课程需要稍微不同的需求,这是我们根据必要的功能将javascript文件包含到页面中的位置.(只有一个入口页面).
我一直试图权衡它是否值得改为AMD,require.js和r.js,或者如果最好继续使用我们当前的系统,其中包括页面上所需的所有内容并将其最小化为一个脚本.
去AMD的最大问题之一就是容易扩展课程似乎更难.例如,有时我们必须稍微调整原始类的行为.因此,我们通过复制原始原型在页面上添加另一个脚本include,扩展原始类,执行使用apply重写的原始函数,然后执行任何其他代码.
您是否可以在不调整原始文件的情况下扩展AMD模块?或者我错过了这一点,我们最好还是坚持我们现在正在做的事情?
我试图用这种方式用模块模式实现继承:
Parent = function () {
//constructor
(function construct () {
console.log("Parent");
})();
// public functions
return this.prototype = {
test: function () {
console.log("test parent");
},
test2: function () {
console.log("test2 parent");
}
};
};
Child = function () {
// constructor
(function () {
console.log("Child");
Parent.call(this, arguments);
this.prototype = Object.create(Parent.prototype);
})();
// public functions
return this.prototype = {
test: function()
{
console.log("test Child");
}
}
};
Run Code Online (Sandbox Code Playgroud)
但是我不能从孩子的实例那里打来电话test2().
var c = new Child();
c.test2(); // c.test2 is …Run Code Online (Sandbox Code Playgroud) 我正在尝试重构一些javascript,我对模块模式感到困惑.
我现在的一种方法是简单地声明一个包含所有组件功能的类
var Foo = function(){
this.Bar = {};
...
}
Run Code Online (Sandbox Code Playgroud)
并创建一个在组件中使用的新实例.但我也读过有关模块模式的内容,我看不出与我所拥有的相比有什么好处,因为它似乎只是以更复杂的方式做同样的事情.也许我只是没有遇到过使它成为更好选择的情况.例如,这样的模式:
var module = (function () {
// private variables and functions
var foo = 'bar';
// constructor
var module = function () {
};
// prototype
module.prototype = {
constructor: module,
something: function () {
}
};
// return module
return module;
})();
var my_module = new module();
Run Code Online (Sandbox Code Playgroud)
与我已经拥有的东西没有明显不同.这种模式让我做了什么,我不能做其他方式?
我刚刚开始学习JavaScript中的模式,并习惯于编写这样的JavaScript:
(function(window){
var privateVar;
var privateFunc = function(param){
//do something
}
return{
publicFunc: function(){
do something
}
}(window));
Run Code Online (Sandbox Code Playgroud)
但最近我发现一些脚本在开头就写了这样的东西:
(function (root, factory) {
if ( typeof define === 'function' && define.amd ) {
define('something', factory(root));
} else if ( typeof exports === 'object' ) {
module.exports = factory(root);
} else {
root.something = factory(root);
}
})(window || this, function (root) {
var privateVar;
var privateFunc = function(param){
//do something
}
return{
publicFunc: function(){
do something
}
});
Run Code Online (Sandbox Code Playgroud)
那么,这段代码在开始时意味着什么呢?它与此模块导出技术之间有什么区别:
var MODULE …Run Code Online (Sandbox Code Playgroud) javascript ×10
module-pattern ×10
closures ×1
constructor ×1
inheritance ×1
js-amd ×1
new-operator ×1
object ×1
shorthand-if ×1