- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
从 Java 到 AngularJS(我对所有 javascript 相关技术都是新手),我正在尝试“翻译”我的想法。我在 Jasmin 中编写了一个对象和一些测试。有些测试有效,但有一个测试一直失败,在我看来,这是一个范围问题。代码如下:
function Invoice() {
var invoicelines = new LinesHandler();
function LinesHandler() {
var lines = [];
function Line() {
var quantity = 0;
var description = '';
var rate = 0;
var total=0;
return {
getQuantity : function() {
return this.quantity;
},
setQuantity : function(quantity) {
this.quantity = quantity;
this.refreshTotal();
},
getDescription : function() {
return this.description;
},
setDescription : function(description) {
this.description = description;
},
getRate : function() {
return this.rate;
},
setRate : function(rate) {
this.rate = rate;
this.refreshTotal();
},
getTotal : function() {
return this.total;
},
refreshTotal : function() {
this.total = this.quantity * this.rate;
}
}
}
return {
getLines : function () {
return lines;
},
addLine : function(line) {
lines.push(line);
},
removeLine : function() {},
editLine : function() {},
createNewLine : function() {
return new Line();
},
getCount : function() {
return lines.length;
},
getLine : function(i) {
return lines[i];
}
}
}
return {
createNewLine : function() {return invoicelines.createNewLine();},
getLinesCount : function() {return invoicelines.getCount();},
addLine : function(line) {invoicelines.addLine(line);},
getLines : function() {return invoiceLines;},
getLinesTotal : function() {
var total = 0;
for (line in invoiceLines) {
total += line.getTotal;
};
return total;
},
getTaxesTotal: function() {}
};
}
这是失败的测试
it('Calculates invoice\'s total while adding lines', function() {
var invoice = scope.invoice;
for(var i = 1, j=10; i < 4; i++, j += 10){
var line = invoice.createNewLine();
line.setQuantity(j);
line.setRate(j);
invoice.addLine(line);
}
expect(invoice.getLinesTotal()).toBe(1400);
});
我尝试像其他函数一样直接访问invoiceLines,我尝试使用this.invoiceLines,我尝试了函数getLines(),但问题是一样的,我一直在firebug中遇到类似的问题:
ReferenceError: invoiceLines is not defined
我不太明白这个问题。为什么其他函数可以看到私有(private)成员,但 getLinesTotal 函数却看不到?还是 for 循环?
提前致谢。
PS:不要犹豫批评代码,我确信这不是用 Javascript 编写代码的最佳方式
最佳答案
关于您的标题(如何在 JavaScript 中进行良好的封装),这里有一个在构建面向对象的 JavaScript 时使用的更好的通用模式:
// Wrap a "class" module in an immediately invoked function expression.
var Parent = (function() {
// Use a function declaration to create the class's constructor function.
function Parent(param) {
// Initialize instance properties from constructor args.
this.param = param;
// Initialize any other instance properties we need.
this.initVar = "foo";
}
// Add instance methods to the class's prototype. These will not exist directly on the instance.
// Instead, JS will look at the instances's prototype to find the value.
// If you try to access a method (or property) that is not defined on this class prototype,
// JS will keep looking up the prototype chain. The order here would go:
// instance -> instance.[[prototype]] (AKA Parent.prototype) -> Object.prototype -> null
Parent.prototype.someMethod = function() {
console.log("Cheese it!");
};
// Here we just make a simple method that logs an instance property to the console.
Parent.prototype.someParentMethod = function() {
console.log(this.param);
};
// Return our now-defined class
return Parent;
// Immediately invoke the wrapping function expression, returning the Parent class.
}());
// Now lets make a class that inherits from Parent.
var Child = (function() {
// Make the child constructor
function Child() {
// If we want we can call the Parent constructor, passing our Child instance as `this`
Parent.call(this, "someParam");
// Do any other child instance initialization
}
// Set the Child prototype to a new instance of Parent. For child, the prototype chain will look like:
// instance -> instance.[[prototype]] (AKA Child.prototype) -> instance.[[prototype]].[[prototype]] (AKA Parent.prototype) -> Object.prototype -> null
Child.prototype = new Parent();
// Point the constructor property to the Child constructor (currently points to Parent)
Child.prototype.constructor = Child;
// Override a parent method
Child.prototype.someMethod = function() {
console.log("Kill all humans!");
};
// Add a method to the Child prototype
Child.prototype.someChildMethod = function() {
console.log("Here be dragons");
};
return Child;
}());
var myParent = new Parent("foobar");
var myChild = new Child();
myParent.someMethod(); // => "Cheese it!"
myChild.someMethod(); // => "Kill all humans!"
myParent.someParentMethod(); // => "foobar"
myChild.someParentMethod(); // => "someParam"
myChild.someChildMethod(); // => "Here be dragons"
myParent.someChildMethod(); // => TypeError: Object #<Parent> has no method 'someChildMethod'
我知道这可能无法直接回答您的问题。然而,它演示了如何通过继承创建封装良好的“类”。原型(prototype)系统可能需要一些时间才能理解 - 我已尽力使注释尽可能清晰。这个想法是,通过将方法附加到原型(prototype),它们只定义一次,因此占用更少的内存。如果实例本身不存在该方法,它将查找其原型(prototype)链以查看它是否在任何地方定义,直到原型(prototype)链最终到达null
。另外,通过操作类原型(prototype),我们可以通过组合实现多重继承。
希望这能有所帮助。如果有任何不清楚的地方请告诉我。
关于javascript - 如何在javascript中做好封装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20100936/
我需要使用封装打印3个变量,并且无法修改主类。 主类声明变量[汽缸、制造商、所有者],并希望使用如下参数创建和打印一个对象: System.out.println (new Vehicle (cyli
我正在研究“Beginning Ruby”这本书,在我进行封装之前一切都进行得很顺利。我明白这段代码在做什么,我只是不知道为什么要用这些方法设置它。 对于那些感兴趣的人 this is the lin
所以我一直在研究面向对象的完整开发 JavaScript 实践,并对以下示例感到好奇。 据我了解,(这对我来说很有意义)以下“ secret ”字段是“私有(private)”的: var MyObj
在面向对象程式设计方法中,封装(英语:Encapsulation)是指,一种将抽象性函式接口的实作细节部份包装、隐藏起来的方法。 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代
封装 被定义为 把一个或多个项目封闭在一个物理的或者逻辑的包中 。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。 抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可
今天我读了一本书,作者写道,在一个设计良好的类中,访问属性的唯一方法是通过其中一个类方法。这是一个被广泛接受的想法吗?为什么封装属性如此重要?不做会有什么后果?我早些时候在某处读到这可以提高安全性或类
今天我接受了软件工程职位的面试。我已经从 stackoverflow 中阅读了很多关于面试的内容。他们向我询问了与 OOP 相关的正常情况。但他们也问我这些: 没有继承就可以封装吗? 没有继承就可以抽
我正在制作一个简单的网站,并编写了gradle构建脚本,该脚本将执行诸如lint并最小化css / html / js之类的事情。 在这一阶段,我刚刚完成了正在运行的CSS,但是只是初始的非结构化格式
下面的幻灯片是指 C++ 语言,它说 "encapsulation is about ensuring the user uses our ADT in a safe way" 但是,如果他可以访问我
尝试设置一个 Person 类 我在尝试将信息封装在类中以使其不会被意外更改时遇到了问题。除了当我尝试使用 setter/getters 进行封装时,该类工作得非常好。我认为问题是这些方法最终会互相循
面向对象的概念:封装、数据抽象和数据隐藏是3个不同的概念,但彼此之间非常相关。所以我很难通过阅读互联网上的信息来完全理解这些概念。一个地方可用的信息与互联网上另一个地方的信息相矛盾。有人可以指导我阅读
我被封装困住了。在我看来,好像我已经按照规则做了一切,但仍然不起作用。虽然我知道我错过了一些东西。我正在使用 Eclipse。 我想要通过创建一副标准 52 张卡片来进行一些练习,并尝试我学到的新东西
在java中,要获取映射中的所有键,我们可以使用方法keySet。但我想知道为什么方法名称不只是 keys ?名称 Set 是否会泄露有关实现的详细信息? 据我了解,Java 是静态类型语言,名称中包
我正在尝试找出如何防止应用程序中的页面变量被全局定义。我想出了一些方法,但我想知道是否有人们使用的通用标准方法。 我使用这种方法得到了我的插件设计模式:http://www.virgentech.co
我有一个 tcp 连接,我想在服务器类的 HandleConnectionAsync 方法中保持打开状态。它将从客户端接收持续更新。 private async void HandleConnecti
这是我类(class)的一个小样本: #include #include using std::string; using std::vector; struct Book { string
我想要类似下面的代码: class Foo{ public: void update() { for( auto dataModifier : _dataModifierLis
这已经困扰我一段时间了,所以我问了一个同事他是否能理解它,现在我来了;) 为什么可以在依赖属性的 PropertyChangedCallback 中访问持有类的私有(private)成员? 让我通过这
我知道封装意味着一个对象不应该直接访问不同对象的成员……但我猜它与公共(public)领域有关?我假设公共(public)方法不会破坏封装..?我只是在这里不清楚,很高兴得到任何解释。 最佳答案
我就废话不多说了,大家还是直接看代码吧~ ? 1
我是一名优秀的程序员,十分优秀!