1、
使用function关键字定义的函数在一个作用域内是可以在任意处调用的(包括定义函数的语句前);而用var关键字定义的必须定义后才能被调用
2、js中实现重载可以通过检测arguments的参数以及类型
3、没有块级作用,如
if(true){
var i=1;
}
alert(i);//输出1
4、先进后出,与先进先出
5、prototype原型
1、每个类都有一个原型对象,原型对象上所有属性对于类的实例都是共享的
2、对象属性搜索顺序:首先解析器会问某个对象有没有某个属性,如果没有,就找对象的原型有没有
3、当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性,如果想恢复原型对象的属性,可通过delete操作符删除实例属性,从而可以重新访问原型中的属性
4、自定义构造函数
//以下程序会依次输出 this is PersonConstructor -> this is Person -> gongkai
function Person(){
alert('this is Person');
}
function PersonConstructor(){
alert('this is PersonConstructor');
}
Person.prototype.constructor=PersonConstructor();//指定Person的构造函数
Person.prototype.name='mokai';//原型的属性对所有实例都是共享的,就像Java的静态变量一样
Person.prototype.age=19;
Person.prototype.sayname=function(){
alert(this.name);
}
var p1=new Person();
p1.name="gongkai";//屏蔽了Person原型name属性
/**
下面此处输出gongkai,这是为什么呢,因为当解析器执行到这句时,
他会读取p1这个对象有没有name属性,如果没有则读取Person原型对象有没有这个对象
**/
p1.sayname();//输出gongkai,来自实例
delete p1.name;
alert(p1.name);//输出mokai,来自原型
5、原型的动态性:实例与原型之间有松散关系,即实例与原型之间的连接是一个指针,而非一个副本,而实例与原型之间的连接是通过实例中的一个 _proto_ 变量引用原型对象
function Person(){};
var p1=new Person();
Person.prototype.name='mokai';
alert(p1.name);//输入mokai
再看一个例子
function Person(){};
var p1=new Person();
Person.prototype={//此处是覆盖了原先的原型对象,意义着在此之前创建的实例对象中的_proto_变量就不是指向现在这个对象了
constructor:Person,
name:'mokai',
age:20,
sayName:function(){
alert(this.name);
}
};
alert(p1.name);//异常
p1.sayname();//异常
6、in操作符
1、用于for-in循环
2、通过判断给定属性在不在对象中,无论该属性是在实例中还是原型中
7、构造函数、原型、实例的关系:每个构造函数都有一个原型对象【prototype】,原型对象都包含一个指向构造函数的指针【prototype.constructor】,而每个实例都包含一个指向原型对象的内部指针【对象的隐式属性_proto_】