韩老师语录:要玩我们就要玩专业点!
1.变量一定要申明,定义,否则会到全局的范围.
{
var i;
i = 1;这个i在本括号内有效。
}
{
i = 1;这个i就变成了全局的了。
}
2. 关于函数
没有对象,所有的都是函数。你可以想象函数本身还可以看成是一个hash表
function ff()
{
};
ff = function(){
};
两种是等价的。
ff.Name = "hello";
ff.Age = 4
以上可见ff就像一个hash表。
3 简单的对象
一个对象就像一个hash表,可以任意设定key。
3.1 json风格
var o = {};这就定义了一个没有属性的对象。
var o = {Name: "hh", Age: 12}这就定义了一个对象有name, age两个属性。
可以包含数组形成任意嵌套
var o = {Name: "hh", Age: 12, Children: [{Name: "hh"}, {Hi: "oo"}]}
一个对象就像一个hash表,可以任意设定key。
前例子中
o['Name'] 等价于 o.Name两种格式是一样的。
遍历一个对象的属性,下面的p是o的属性,而o[p]就是其值(这里不能用o.p)
for(var p in o){
alert("o' property " + p + " is " +o[p]);
}
3.2模仿类的方式定义类以及对象的生成
Person = function(){
this._name = null;//这个可以要可不要。
};
Person.prototype.getName = function(){
return this._name;//注意,this.一定要,否则错误。
};
Person.prototype.setName = function(name){
return this._name = name;
};
var p = new Person();
p.setName("hh");
alert(p.getName());
prototype,每个函数都有一个prototype,是一个hashtb。所有的Person的对象共享该prototype表。
p.setName执行时,他会先从p本身查找看p这个hashtb上是否有setName这个属性,没有
就会查找其关联的prototype表中是否有setName属性(如果都查找不到,就返回undefined)。
而这个例子中就有。因为prototype只有一个
所以放共享的东西最好。比如类的成员函数。如果你放的是一个数组,那就大家共享了
Person.prototype.children = [];
var p1 = new Person();
p1.children[0] = "1";
p2 = new Person();
p2.children[1] = "2";
这两个p1, p2共享了一个数组children.
如果p1.children = [];
这时p2.children会受影响马?
不会,因为p1这个hash上设定了新的[]。但不会影响prototype上的children 属性。
p2并没有设定自己的children属性。还是会用protoype上的属性。
下面是另外一种类的申明方法,等价上面的。从这个也可以看出prototype是一个hash表
//这个代表将一个对象(有setName, getName两个属性)设定给函数的prototype属性。
于是这个函数Person生成的对象都拥有该对象作为prototype.
Person = function(){
};
Person.prototype = {
getName: function(){
return this._name;//注意,this.一定要,否则错误。
},
setName: function(name){
this._name = name;
}
};
3.3关于this的理解
this就是发起那个函数调用的实体。
p.setName就是这个p.
有些特殊的函数可以改变函数的发起者,即改变this。
apply是所有函数具有的一个东西(理解成一个方法好了)
function PP(xx, yy){
this.....
}
var o = {};
PP.apply(o, [1, 2]);
这时1, 2就是xx,yy.this就是o
PP.call(o, 1, 2);和apply效果一样。
apply还接受一个特殊的参数arguments.
function(x, y){
var o;
PP.apply(o, arguments);这个arguments就是[x, y]这个数组。
}
4. namespace。没有名字空间,只有模仿。
var MyNamesapce = {};
MyNamesapce.Utils = {};
以下是一个简单的判定名字空间是否存在然后不存在就定义的方法
var MBO = MBO || {
app:{},
util:{}
};
如果MBO不存在就定义他,并还有子space ,app和util.
有了名字空间,我们再定义类
MBO.app.Application = function(){
};
...
5 注意null, undefined等的问题,看资料
6 关于闭包。
少用,有的浏览器,会产生资源泄漏。
7 关于引用顺序
要被引用的,必须在使用前面引用。
8 关于数组
var a = ["a1", "b1"];
数组本质上就是一个hashtb。
可以用
for(var p in a){
a[p];
}
发现p就是0, 1这些index。而a[p]就是元素的值。
因此, a[0] = 1; a[100] = 2;
并不会产生98个浪费的空洞。因为它是hashtb.