Professional javascript For Web Developers 第2版读书笔记(更新中)
1.为了兼容XHtml,对于inline javascript,把代码包裹在//<!CDATA[与//]]>之间。
2.使用外部javascript引用的好处:良好的可维护性(js文件可放在同一个目录中) 、缓存(当2个文件引用同一个外部JS时,js文件只下载一次)、避免了XHTML兼容性的问题。
3.一般在<body>标签底部引入javascript,目的是为了减少当javascript过大,浏览器编译js而导致页面空白的时间 (整个DOM是按顺序执行,而页面的render是等浏览器接收到<body>标签才开始,若js很大又放在body前面,则会导致页面等待,放在后面则可以等页面载入成功再下载js,对用户来说体验更好)
4. javascript有5种类型:undefined,null,bool,number,string。object作为一种复合类型(键值对)存在。
typeof undefined 返回 undefined.
typeof null或者obejct 返回object.
typeof string 返回 string
typeof number 返回 number
typeof bool 返回 bool
typeof function 返回 function (function在ECMAScript也被认为是object,但是它有一些特殊属性,因此只能用typeof才能区分其他object和function)
typeof RegExp返回function(说明RegExp是function)
5. 声明过的变量,如果未赋初值,则默认会设置为undefined,如果用typeof运算符操作为未声明过的变量也会返回undefined。
6.undefined实际上是从null衍生而来,因此 undefined == null 返回 true,但不能认为undefined就是null,null可以理解一个空指针,即变量有值但是为null。 null和undefined没有toString()方法,用String()变换则返回“null"和”undefined“
7.javascript对大小写敏感,因此true和false才是bool类型,其他的任意大小写组合都不认为是bool类型
8.NaN即Not a number,NaN与参与任何的运算数字都返回NaN,而且NaN==NaN返回false
9.恒等运算符 “===”和非恒等运算符 ”==“ 的区别在于恒等不会进行类型转换,而非恒等符会进行转换(cast or convertion)
10.for...in语句用来遍历object中所有属性,但是是无序的。
11.function如未指定返回值,则默认为undefined,function在其代码块内部都会有一个arguments数组来存储传进来的参数,数组顺序和传进来的参数顺序相同,arguments对象是值传递的。
12.javascript中5种基础类型是存放在栈,引用类型Object存放在堆。instanceof用来判断实例属于什么类型,如果是基础类型始终返回false,instanceof Object始终返回true, "sd" instanceof String 返回true
13.作用域(scope chain)在js中和其他语言不同,js中不是以代码块{}来区分作用域,而是有个scope chain。最外层的scope通常是global范围的即window,最内层一般属于function内定义的局部变量。
function changeColor(){
var anotherColor = “red”;
function swapColors(){
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
//color, anotherColor, and tempColor are all accessible here
}
//color and anotherColor are accessible here, but not tempColor
swapColors();
}
//only color is accessible here
changeColor();
scope chain为:
window
coloranotherColor
swapColors()
tempColor
changeColor()
访问性是有内到外。
然而no-block level scopes
var color = “blue”;
}
alert(color); //”blue”
for (var i=0; i < 10; i++){
doSomething(i);
}
alert(i); //10
14.加了var关键字的变量为局部变量,没家var会默认添加到当前的全局变量中,即window对象中。但是强烈建议不要省略var,在初始化变量之前要声明它
15.function内部包含2个特殊的对象arguments和this,arguments.callee指向的是当前拥有这个arguments的函数指针,arguments属于哪个函数,arguments.callee就是指向哪个函数。this总是当前函数执行时所属的作用域
var o = { color: “blue” };
function sayColor(){
alert(this.color);
}
sayColor(); //”red”
o.sayColor = sayColor;
o.sayColor(); //”blue”
16.function也属于对象,因此它有2个基本的属性length和prototype。length表示这个function所具有的显示命名的参数个数。prototype是设置类型的方法和属性,而不是属于某个具体实例,类似与c#的静态方法,后面详细介绍
17.apply和call方法基本实现相同的功能。apply方法接受2个参数,一个是运行方法所属的作用域,一个是有参数组成的数组。call方法第一个参数是运行方法所属的作用域,剩下的的参数是要传递的进来的
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments); //passing in arguments object
}
function callSum2(num1, num2){
return sum.apply(this, [num1, num2]); //passing in array
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20
return num1 + num2;
}
function callSum(num1, num2){
return sum.call(this, num1, num2);
}
alert(callSum(10,10)); //20
18.Constructor是javascript中的构造函数,它跟一般的函数的主要区别在于:
1.没有明确的构造对象。
2.属性和方法函数直接指派到this指针上。
3.没有return语句返回值
如:
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person(“Nicholas”, 29, “Software Engineer”);
var person2 = new Person(“Greg”, 27, “Doctor”);
每个具体的实例都有constructor属性,它指向实例所属的类型,
alert(person2.constructor == Person); //true
自定义构造函数构造的类型还可以通过instanceof运算符来判定实例的类型。
alert(person1 instanceof Person); //true
alert(person2 instanceof Object); //true
alert(person2 instanceof Person); //true
要注意的是:构造一个实例要通过new关键字,这也是constructor和一般function调用方式的不同。另外,这种构造函数的方式有个缺陷就是每个实例都会构造方法,即上例的person1的sayName和person2的sayName是不一样的,通过
alert(person1.sayName == person2.sayName); //false 可知
最好的实现构造函数的方式是prototype(原型模式)
}
Person.prototype.name = “Nicholas”;
Person.prototype.age = 29;
Person.prototype.job = “Software Engineer”;
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //”Nicholas”
var person2 = new Person();
person2.sayName(); //”Nicholas”
alert(person1.sayName == person2.sayName); //true
prototype的工作原理如下:
所有的prototypes默认都会自动产生一个constructor属性指向类型本身,如 Person.prototype.constructor指向Person,其他的属性也会被添加到prototype上。每当调用constructor生成一个实例的时候,实例内部会产生一个_proto_属性指向Prototype。虽然实例内部没有定义方法,但是可以调用sayName方法(实际上就是一种继承关系 ),需要注意的是_proto_是没办法通过实例访问的,但是为了验证这种关系存在,isPrototypeOf方法可以检验
alert(Person.prototype.isPrototypeOf(person2)); //true
一旦实例覆盖了prototype的定义的属性值,子类便丧失了访问父类相同属性值的能力,除非用delete关键字
}
Person.prototype.name = “Nicholas”;
Person.prototype.age = 29;
Person.prototype.job = “Software Engineer”;
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
person1.name = “Greg”;
alert(person1.name); //”Greg” - from instance
alert(person2.name); //”Nicholas” - from prototype
delete person1.name;
alert(person1.name); //”Nicholas” - from the prototype
hasOwnProperty()方法用来判定属性是属于prototype还是实例本身
}
Person.prototype.name = “Nicholas”;
Person.prototype.age = 29;
Person.prototype.job = “Software Engineer”;
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
alert(person1.hasOwnProperty(“name”)); //false
person1.name = “Greg”;
alert(person1.name); //”Greg” - from instance
alert(person1.hasOwnProperty(“name”)); //true
下面的图说明了关系是如何
判断某个属性是属于实例还是原型的方法可以用
{
return !object.hasOwnProperty(name) & & (name in object);
}
19.默认情况下类型的prototype.constructor会指向类型本身,但如果出现下列情况
}
Person.prototype = {
name : "Nicholas",
age : 29,
job : "Software Engineer",
sayName : function () {
alert(this.name);
}
};
var person = new Person();
alert(person instanceof Object); //true
alert(person instanceof Person); //true
alert(person.constructor == Person); //false
alert(person.constructor == Object); //true
则Person.prototype.constructor会指向一个新的Object对象,而不是原来的Person对象,尽管instanceof仍然返回true,如果为了让constructor指向Person则需要改成
}
Person.prototype = {
constructor: Person,
name : “Nicholas”,
age : 29,
job : “Software Engineer”,
sayName : function () {
alert(this.name);
}
};
20.prototype上动态修改或者添加方法属性是可以让实例获取到的,因为实例有指向原型(_proto_)的指针。
如:
Person.prototype.sayHi = function(){
alert(“hi”);
};
person.sayHi(); //”hi” - works!
但如果修改的是prototype,则修改的是prototype的指针
如:
}
var person = new Person();
Person.prototype = {
constructor: Person,
name : “Nicholas”,
age : 29,
job : “Software Engineer”,
sayName : function () {
alert(this.name);
}
};
person.sayName(); //error
用如下的图来解释:
posted on 2010-07-20 00:08 MoonWalker 阅读(351) 评论(2) 编辑 收藏 举报