下面是阅读精通JavaScript书做的相关笔记。
JS中的函数重载
函数重载必须依赖两件事情:判断传入参数数量的能力和判断传入参数类型的能力,在js中每个函数都带有一个仅在这个函数范围内作用的变量,称之为参数argument,它是一个包含所有传给函数参数的伪数组,所以并不是正的数组,但是我们不可以去修改它。其实这个就相当于一个池,将参数全部都保存在里面,之后在用的时候去取,只是这个池我们看不见。是语言自己去找。
JS中2种常见的类型检查
- :typeof()操作符
typeof n==”string”;
n为变量名,判断其是否为字符串类型。其实这个只适用于变量类型不是object和array的类型。
- :构造函数(constructor)
其实我们应该知道JS中每一个对象里面都有一个默认的构造函数,我们可以利用这个构造函数来进行判断;
var num,str; if (num.constructor == String) { num = parseInt(num); } if (str.constructor == Array) { str=str.join(‘,‘); }
闭包
闭包意味着内层的函数可以引用存在于包围它的函数内的变量,即使外层函数执行已经终止,
其实这个可以这样理解:就是说函数里面的函数对象调用了外面的变量,如果里面的对象不释放,那么外面的变量将会一直存在,保持为一种僵死的状态,直至里面的对象不在调用即可死亡。这样的话,外面的变量占用的内存空间将会一直保存着。
上下文对象
这里的上下文对象,是指我们代码的总负责人是谁,通常我们使用this来表示,这个变量永远指向当前代码所在的对象中。全局对象是window对象属性。
这里的上下文对象可以进行切换为windows对象。
function changeColor(color) { this.style.color = color; } changeColor("white"); //这样会失败,因为window对象没有style属性; var main=document.getElementById(‘main‘); changeColor.call(main,"black"); function setBodyColor(){ changeColor.apply(document.body,arguments); } setBodyColor("black");
JS中的对象
JS中没有类的概念,对于其余的面向对象语言中大多就是对于实例化某个具体类的实例,但是在JS中不用,JS中对象本身可以用来创建新对象,而对象也可以继承自其它对象,这是原型化继承;其实在JS中对象就是我们的函数,任何函数都可以被实例化为一个对象。
function User(name) { this.name = name; } //1:当作对象使用 var me = new User("My Name"); alert(me.name); //当作函数使用,此时的name是为全局的window对象; User("A Hui"); alert(window.name);
- 公共方法
公共方法在对象的上下文中是用户最终接触到的,要实现这种在对象的每个实例中都可以使用的公共方法,必须使用一个叫prototype(原型)的属性,这个属性包含一个对象,这个对象可以作为所有新副本的基引用。本质上说,所有对象原型的属性都能在对象的每个实例中找到。这就是js中的继承。
//这里的this指的是那个对象,谁调用函数,就是谁。刚开始是window对象 function User(name,age){ this.name=name; this.age=age; } User.prototype.getName=function(){ return this.name; }; User.prototype.getAge=function(){ return this.age; }; var user=new User("andyahui",23); alert(user.getName()); //这里是函数就需要使用() alert(user.getAge());
- 私有方法
私有方法和私有变量只容许其它的私有方法,变量和特权方法访问。
下面这个代码就是一个私有方法,但是外面访问不了。报错。
function Classroom(students, teacher) { function disp() { alert(this.name.join(",")); } this.students = students; this.teacher = teacher; disp(); } var classq = new Classroom(["John", "Bob"], "MR.Smith"); classq.disp();
- 特权方法
这个是Douglas Crockford采用的一个名词,用来指代那些查看并处理(对象)私有变量的同时容许用户以公共方法的方式访问的方法;
function User(name, age) { var year = (new Date()).getFullYear() - age; this.getYearBorn = function() { return year; }; } var user = new User("ahui", 23); alert(user.getYearBorn()); //1993 alert(user.year); //undefined
特权方法是动态生成的,因为只有调用方法的时候才会去生成必要的数据。不是在代码第一次编译的时候就生成的。虽然这个技巧要比继承prototype上面绑定一个简单的方法开销更大,但功能也更强大,更灵活。(也就是year变量的作用域是函数里面,外面的对象访问不到。)
动态生成代码的能力不可小视,可以根据运行时变量来生成代码,这也是其它语言里的宏。
我不会告诉别人我是一个程序员,如果一定要取一个称号的话:我就是”艺术的缔造者”。