注意:从ECMAScript版本3或5的角度提出了这个问题.在ECMAScript 6发布中引入新功能后,答案可能会过时.
varJavaScript中关键字的功能到底是什么,有什么区别
var someNumber = 2;
var someFunction = function() { doSomething; }
var someObject = { }
var someObject.someProperty = 5;
Run Code Online (Sandbox Code Playgroud)
和
someNumber = 2;
someFunction = function() { doSomething; }
someObject = { }
someObject.someProperty = 5;
Run Code Online (Sandbox Code Playgroud)
?
你什么时候使用其中任何一个,为什么/它做什么?
好吧,我试图弄清楚这有可能以任何方式.这是代码:
a=function(text)
{
var b=text;
if (!arguments.callee.prototype.get)
arguments.callee.prototype.get=function()
{
return b;
}
else
alert('already created!');
}
var c=new a("test"); // creates prototype instance of getter
var d=new a("ojoj"); // alerts already created
alert(c.get()) // alerts test
alert(d.get()) // alerts test from context of creating prototype function :(
Run Code Online (Sandbox Code Playgroud)
如你所见,我试图创建原型getter.为了什么?好吧,如果你写这样的东西:
a=function(text)
{
var b=text;
this.getText=function(){ return b}
}
Run Code Online (Sandbox Code Playgroud)
......一切都应该没问题......但实际上每次创建对象时 - 我都会创建使用内存的getText函数.我想在记忆中有一个原型功能可以做同样的事情...任何想法?
编辑:
我试过Christoph给出的解决方案,它似乎是目前唯一已知的解决方案.它需要记住id信息以从上下文中检索值,但是整个想法对我来说很好:) Id只是要记住的一件事,其他一切都可以在内存中存储一次.实际上,您可以通过这种方式存储许多私有成员,并且只能使用一个id.实际上这让我很满意:)(除非有人有更好的主意).
someFunc = function()
{
var store = new Array();
var guid=0;
var someFunc = function(text)
{
this.__guid=guid;
store[guid++]=text; …Run Code Online (Sandbox Code Playgroud) 我试图深入了解原型继承和类创建(我知道,还有其他方法,但为了这个目的,我试图掌握原型.)我的问题是:使用下面的代码示例,是有没有办法内部创建私有变量Tree,并Fruit不会与该函数返回,但仍是原型函数访问genus和bulk?
var Tree = function ( name, size ) {
this.name = name;
this.size = size;
};
Tree.prototype.genus = function(){
return ((typeof this.name !== 'undefined') ? this.name : 'Hybridicus Maximus');
};
Tree.prototype.bulk = function(){
return ((typeof this.size !== 'undefined') ? this.size : '8') + ' ft';
};
var Fruit = function( name, size ) {
this.name = name;
this.size = size;
};
Fruit.prototype = new Tree();
// Fruit.prototype = Tree.prototype; -- I …Run Code Online (Sandbox Code Playgroud) 这是我刚发布的问题的后续跟进.我想知道你在使用MyClass.prototype定义方法时如何处理javascript clases中的成员变量.
如果在构造函数中定义所有方法:
function MyClass(){
this.myMethod = function(){}
}
Run Code Online (Sandbox Code Playgroud)
您可以很好地声明成员变量并从方法中访问它们:
function MyClass(){
var myVar = "hello";
this.myMethod = function(){
alert(myVar);
}
}
Run Code Online (Sandbox Code Playgroud)
当使用Object.prototype技术时,你会失去这种精确性,并且必须这样做;
function MyClass(){}
MyClass.prototype.myVar = "hello";
MyClass.prototype.myMethod = function(){alert(this.hello)};
Run Code Online (Sandbox Code Playgroud)
每次访问成员变量时,我都不会疯狂地写"this".我想使用Object.prototype方法出于内存和灵活性的原因,但在语法方面看起来很笨拙.这是你们一般的工作方式吗?
谢谢,
-摩根
我有以下javascript
function person() {
//private Variable
var fName = null;
var lName = null;
// assign value to private variable
fName = "Dave";
lName = "Smith";
};
person.prototype.fullName = function () {
return this.fName + " " + this.lName;
};
var myPerson = new person();
alert(myPerson.fullName());
Run Code Online (Sandbox Code Playgroud)
我试图在javascript中理解面向对象的技术.我有一个简单的人物对象,并为其原型添加了一个函数.
我期待警报有"戴夫史密斯",但我得到了"underfined underfined".为什么这样,我该如何解决?
所以这是着名的JavaScript模块模式的一个例子:
var Person = (function() {
var _name; // so called 'private variable'
function Person(name) {
_name = name;
}
Person.prototype.kill = function() {
console.log(_name + ' has been shot');
};
return Person;
})();
var paul = new Person('Paul');
paul.kill();
Run Code Online (Sandbox Code Playgroud)
到目前为止这么好吧?这会记录'Paul has been shot'到控制台,这是我们想要的.
但.
是_name一个真正的私有变量?我将私有变量定义为属于对象实例的变量,外部世界无法访问该变量.最后一部分工作,我无法_name从封闭外部访问.
但如果我这样做:
var paul = new Person('Paul');
var bran = new Person('Bran');
paul.kill();
bran.kill();
Run Code Online (Sandbox Code Playgroud)
然后这将记录'Bran has been shot'两次.那里没有保罗.所以,_name实际上是与所有实例共享我的Person对象的.这就是我将其定义为"静态变量",尽管它也无法从外部访问.
那么有没有办法用模块模式创建一个真正的私有成员变量?一个不是静止的.
同样发生的事情是this._name …
在ES5中,您可以使用私有和公共变量模拟一个类,如下所示:
car.js
function Car() {
// using var causes speed to be only available inside Car (private)
var speed = 10;
// public variable - still accessible outside Car
this.model = "Batmobile";
// public method
this.init = function(){
}
}
Run Code Online (Sandbox Code Playgroud)
但是在ES6中,你不能再在构造函数之外声明变量,这使得实际上更难以以OOP方式使用类!
您可以使用此方法在构造函数中声明变量,但这会使它们默认公开.这非常奇怪,因为ES6 DOES有一个get/set关键字!
class Vehicle {
constructor(make, year) {
// the underscore is nice, but these are still public!
this._make = make;
this._year = year;
}
// get and set can be handy, but would make more sense
// …Run Code Online (Sandbox Code Playgroud) 我目前正在研究在JavaScript中构建类的不同模式.但不管我看到什么模式,还有一些我不太确定的事情.
var ItemManager = (function()
{
var p = function()
{
this.items= [];
};
p.prototype.addItem = function(item)
{
var self = this;
self.items.push(item);
};
return p;
}());
Run Code Online (Sandbox Code Playgroud)
我创建了简单的类ItemManager,这个类得到了addItem函数,用于将任何项添加到集合中.现在我真的不希望表示集合的变量项是公共的,这个变量应该是私有的,但我没有看到任何可能的方法来使用prototyped方法来访问私有变量.
那么这种情况下的最佳做法是什么?只是不使用私有变量?
[是的,我已经阅读了几个类似问题的答案,但没有真正得到我正在寻找的答案,所以无论如何我都会问我的问题.]
在下面的代码中,如何将方法setSecret和tellSecret放在Secret的原型中,同时仍然保持对私有实例变量_secret的访问,并产生相同的输出?
我试过这个(参见jsbin)将方法放在原型中,但改变了输出.
function Secret() {
// ===== private =====
var _secret;
// ===== public =====
this.setSecret = function (secret) {
_secret = secret;
};
this.tellSecret = function () {
console.log(_secret);
};
}
var secretA = new Secret();
var secretB = new Secret();
secretA.setSecret("AAA");
secretB.setSecret("BBB");
setTimeout(function () {
console.log("Secret A");
secretA.tellSecret();
console.log("Secret B");
secretB.tellSecret();
}, 1000);
// ===== output =====
Secret A
AAA
Secret B
BBB
Run Code Online (Sandbox Code Playgroud) 我刚刚发现Object.defineProperty并且因为我对 C# 最熟悉,所以我想在构造函数中使用访问器属性,例如:
function Base(id) {
var _id = id;
Object.defineProperty(this,"ID",{
get: function() { return _id; },
set: function(value) { _id = value; }
})
}
function Derived(id, name) {
var _name = name;
Base.call(this,id);
Object.defineProperty(this,"Name",{
get: function() { return _name; },
set: function(value) { _name = value; }
})
}
Derived.prototype = Object.create(Base.prototype);
Derived.constructor = Derived;
var b = new Base(2);
var d = new Derived(4,"Alexander");
console.log(b.ID);
console.log(d.ID, d.Name);
d.ID = 100;
console.log(d.ID, d.Name);Run Code Online (Sandbox Code Playgroud)
这打印:
2
4 …
我如何使sku私有但允许getter访问它:
var Product = function (sku) {
this.sku = sku;
};
Product.prototype.getSku = function() {
return this.sku;
}
module.exports = {Product: Product};
Run Code Online (Sandbox Code Playgroud) 首先,这可能是基于主要观点的,所以我正在寻找技术原因和普遍接受的最佳实践来做一件事或另一件事.
如果我写一个"类"并创建它的成员,我可以像这样访问实例属性
function MyClass(){
var self = this;
self.foo = 'bar'
}
var instance = new MyClass();
instance.foo = '420';
Run Code Online (Sandbox Code Playgroud)
但是,我也可以创建一个设置属性的方法,这样就不需要了解所需类的内部结构
MyClass.prototype.setFoo = function(prop){
this.foo = prop;
};
Run Code Online (Sandbox Code Playgroud)
考虑到专业发展,是否有理由偏好另一种变体?
我有三个脚本文件.main.js,script1.js,script2.js.
main.js只是将脚本包含在文档中:
function IncludeJs(sFileName) {
document.writeln('<script type="text/javascript" src="' + sFileName + '"></script>');
}
IncludeJs("../script1.js");
IncludeJs("../script2.js");
Run Code Online (Sandbox Code Playgroud)
script1.js和script2.js代码位于相同的命名空间下.
script1.js:
var sharedNamespace = sharedNamespace || {};
(function () {
"use strict";
function func1(){
....
}
}).apply(sharedNamespace );
Run Code Online (Sandbox Code Playgroud)
script2.js:
var sharedNamespace = sharedNamespace || {};
(function () {
"use strict";
function func2(){
return func1();
}
}).apply(sharedNamespace );
Run Code Online (Sandbox Code Playgroud)
func2无法正常工作,因为func1未定义.我如何将script1.js和script2.js放在同一范围内的共享变量?
解决方案sharedNamespace.func1 = function(){}对我来说是最糟糕的,因为我不想将此功能公开给使用我的库的客户端...
javascript ×13
oop ×3
class ×2
ecmascript-5 ×1
ecmascript-6 ×1
keyword ×1
modularity ×1
private ×1
properties ×1
prototype ×1