为对象添加方法的一种方法就是简单附加一个函数值:
<html> <head> <meta charset="utf-8" /> <script type="text/javascript"> function print(str) { document.write(str + "<br />"); } var rabbit = {}; rabbit.speak = function(line) { print("The rabbit says '" + line + "'"); }; rabbit.speak("I'm alive."); </script> </head> </html>
在函数当作方法使用时候,通过this来指向相关的对象:
<html> <head> <meta charset="utf-8" /> <script type="text/javascript"> function print(str) { document.write(str + "<br />"); } function speak(line) { print("The " + this.adjective + " rabbit says '" + line + "'"); } var whiteRabbit = {adjective : "white", speak : speak}; var fatRabbit = {adjective : "fat", speak : speak}; whiteRabbit.speak("Oh my ears and whiskers, how late it's getting!"); fatRabbit.speak("I could sure use a carrot right now."); </script> </head> </html>
而apply方法和call方法运用如下:(两种方法类似)
<html> <head> <meta charset="utf-8" /> <script type="text/javascript"> function print(str) { document.write(str + "<br />"); } function speak(line) { print("The " + this.adjective + " rabbit says '" + line + "'"); } var whiteRabbit = {adjective : "white", speak : speak}; var fatRabbit = {adjective : "fat", speak : speak}; //注意:apply的第二个参数为一个数组 speak.apply(whiteRabbit, ["Oh my ears and whiskers, how late it's getting!"]); speak.call(fatRabbit, "I could sure use a carrot right now.") </script> </head> </html>
通过new来达到目的:
<html> <head> <meta charset="utf-8" /> <script type="text/javascript"> function print(str) { document.write(str + "<br />"); } function Rabbit(adjective) { this.adjective = adjective; this.speak = function(line) { print("The " + this.adjective + " rabbit says '" + line + "'"); }; } var killerRabbit = new Rabbit("killer"); killerRabbit.speak("GRAAAAAAAAAAAAAAAAH!"); </script> </head> </html>
记住:构造函数构造了一个对象,而不是一个函数!你可以给对象添加属性,但是不能给函数添加属性:
<html> <head> <meta charset="utf-8" /> <script type="text/javascript"> function print(str) { document.write(str + "<br />"); } function Rabbit(adjective) { this.adjective = adjective; this.speak = function(line) { print("The " + this.adjective + " rabbit says '" + line + "'"); }; } //定义一个对象 var killerRabbit = new Rabbit("killer"); killerRabbit.say = "hello world"; killerRabbit.speak("GRAAAAAAAAAAAAAAAAH!"); print(killerRabbit.say); //定义一个函数 var funcRabbit = Rabbit("not-killer"); funcRabbit.say = "what"; print(funcRabbit.say); //并没有输出 </script> </head> </html>
所有对象均有原型,但是有一种情况是:对象本身并没有属性,但是原型有(原型可以理解为基类):
<html> <head> <meta charset="utf-8" /> <script type="text/javascript"> function print(str) { document.write(str + "<br />"); } var noCatsAtAll = {}; if ("constructor" in noCatsAtAll) { print("it's error"); } </script> </head> </html>
我们可以通过函数hasOwnProperty来判断是否为自身的属性.以下函数返回自身的属性:
<html> <head> <meta charset="utf-8" /> <script type="text/javascript"> function print(str) { document.write(str + "<br />"); } Object.prototype.properties = function() { var result = []; for (var property in this) { if (this.hasOwnProperty(property)) { result.push(property); } } return result; }; debugger; var test = {"x" : 10, "y" : 3}; var array = test.properties(); for (var i = 0; i < array.length; i++) { print(array[i]); } //注意:这里不能用var i in array方式来遍历数组,因为array会继承原型properties属性 for(var i in array) { print(i + ":" + array[i]); } </script> </head> </html>
我们可以独自编写构造函数并指定原型即可:
<html> <head> <meta charset="utf-8" /> <script type="text/javascript"> function print(str) { document.write(str + "<br />"); } function Dictionary(startValues) { this.values = startValues || {}; } Dictionary.prototype.store = function(name, value) { this.values[name] = value; }; Dictionary.prototype.lookup = function(name) { return this.values[name]; }; Dictionary.prototype.contains = function(name) { return Object.prototype.propertyIsEnumerable.call(this.values, name); }; Dictionary.prototype.each = function(action) { forEachIn(this.values, action); }; function forEachIn(array, action) { for (var key in array) { action(key, array[key]); } } var colors = new Dictionary({Grover : "blue", Elmo : "red", Bert : "yellow"}); print(colors.contains("Grover")); print(colors.contains("constructor")); colors.store("Ernie", "orange"); debugger; colors.each(function(name, color){ print(name + " is " + color); }); </script> </head> </html>
大概如下:#代表墙,字母o代表困从,空格代表空白的地方.
var thePlan = ["###########################", "# # # o ##", "# #", "# ######### #", "## # # # #", "##### o o ## ##", "### o o o o #", "###########################"];
function Point(x, y) { this.x = x; this.y = y; } Point.prototype.add = function(other) { return new Point(this.x + other.x, this.y + other.y); }
我们可以用单数组来设计网格.假设点为(x,y),而网格的宽度为width,则我们可以得到此点在数组中的索引:x + y * width.
//网格的设计 function Grid(width, height) { this.width = width; this.height = height; this.cells = new Array(width * height); } Grid.prototype.valueAt = function(point) { return this.cells[point.y * this.width + point.x]; }; Grid.prototype.setValueAt = function(point, value) { this.cells[point.y * this.width + point.x] = value; }; Grid.prototype.isInside = function(point) { return point.x >= 0 && point.y >= 0 && point.x < this.width && point.y < this.height; }; Grid.prototype.moveValue = function(from, to) { this.setValueAt(to, this.valueAt(from)); this.setValueAt(from, undefined); }; Grid.prototype.each = function(action) { for (var y = 0; y < this.height; y++) { for (var x = 0; x < this.width; x++) { var point = new Point(x, y); action(point, this.valueAt(point)); } } };