* 语言特性 *
---------------------------------------------------------------------------
1.引用
引用指向的只能是具体的对象,而不是另一个引用
注意: 一些对象修改会生成新对象,如字符串拼接
2.重载
重载依赖: A.判断传入参数数量; B.判断传入参数类型
伪数组: argument
3.类型检查
1) 方式一: 使用 typeof 操作符
if(typeof num == 'string') ...
2) 方式二: 构造函数
if(num.constructor == String) ...
4.作用域
--> 作用域由函数划分而不是由块划分
--> 基于浏览器的javascript中,所有属于全局作用域的变量其实都是window对象的属性
--> 如果变量没有显示定义,它就是全局定义的
5.闭包
1) 优化编码方式
setTimeout('otherFunction('+num+','+num2+')', 1000);
可改为形如:
function someFunction(msg, time){ setTimeout(function(){ alert(msg); }, time); }
2) 实现函数Curry化
function addGenerator(num){ return function(toAdd){ return num + toAdd; }; } var addFive = addGenerator(5); alert(addFive(4) == 9);
3) 使用匿名函数隐藏全局作用域变量
(function(){ var msg = ''; //... })();
4) 使用匿名函数激发出创建多个使用闭包的函数所需的作用域
var obj = document.getElementById('main');
var items = ['click', 'mouseover'];
for(var i=0,len=items.length; i<len; ++i){
(function(){
var item = items[i];
//如果没有外层匿名函数,这个闭包将只注册mouseover事件
obj['on'+item] = function(){
alert('正在'+item);
}
})();
}
6.上下文
var obj = { yes: function(){ this.val = true; }, no: function(){ this.val = false; } }; alert(obj.val==null); //没有val属性 obj.yes(); alert(obj.val==true); //val属性为true window.no = obj.no; //切换了上下文 window.no(); alert(obj.val==true); //obj的val不变 alert(window.val==true); //window的val被更新
--> 使用 call 或 apply 调用,更易于理解
* 面向对象基础 *
---------------------------------------------------------------------------
1.公共方法
function User(name){ this.name = name; } //其上下文是实例化后的对象 User.prototype.getName = function(){ return this.name; }
核心在于prototype属性的理解应用
2.私有方法
function Classroom(teachers){ var disp = function (){ //... 私有方法的一些操作 } this.teachers = teachers; disp(); } var class = new Classroom(['Mr.Smith', 'Mr.Lee']); //class.disp(); 这样写会报错,disp对外不可见
3.特权方法
function User(name, age){ var year = (new Date()).getFullYear() - age; this.getYearBorn = function(){ return year; } }
特权方法(getYearBorn)是动态生成的,比往prototype上绑定方法开销大,但更灵活
4.静态方法
User.cloneUser = function(user){ return new User(user.getName(), user.getAge()); }
1) 唯一优点: 保证对象的命名空间整洁
2) 仅为组织代码而使用的方法
3) 实质与其他一般函数没区别
* 标准化面向对象的代码 *
---------------------------------------------------------------------------
1.原型式继承
1) 原理: 对象的构造函数可以从其他对象中继承方法,它创建出一个原型对象后,所有
其他的新对象都可以基于这个原型对象来构建
2) 原型式继承的设计适用于单继承而非多继承
3) 使用示例:
function Person(name){ this.name = name; } Person.prototype.getName = function(){ return this.name; } function User(name, password){ this.name = name; this.password = password; } User.prototype = new Person(); //关键代码!继承Person对象的所有方法 User.prototype.getPassword = function(){ return this.password; }
2.类式继承
Function.prototype.method = function(name, fn){ this.prototype[name] = fn; return this; } Function.method('inherits', function(parent){ var depth = 0; var proto = this.prototype = new parent(); this.method('uber', function uber(name){ var func, ret, v = parent.prototype; if(depth){ for(var i=depth; i>0; --i){ v = v.constructor.prototype; } func = v[name]; }else{ func = proto[name]; if(func == this[name]){ func = v[name]; } } ++depth; ret = func.apply(this, Array.prototype.slice.apply(arguments, [1])); --depth; return ret; }); return this; }); Function.method('swiss', function(parent){ for(var i=1,len=arguments.length; i<len; ++i){ var name=arguments[i]; this.prototype[name] = parent.prototype[name]; } return this; }); function Person(name){ this.name = name; } Person.method('getName', function(){ return this.name; }); function User(name, password){ this.name = name; this.password = password; } User.inherits(Person); User.method('getPassword', function(){ return this.password; }); User.method('getName', function(){ return 'My name is ' + this.uber('getName'); });