reading book:《javascript高级程序设计第二版》
布尔变量:
var msg;
if (msg == undefined) //true
if (undefined == null) //true
false:
empty string ""
0, NaN
null
defined
//=============================
var n = 10
n.toString('2') //1010
类的赋值为引用赋值
var obj1 = new Object();
var obj2 = obj1;
obj1.name = “Nicholas”;
alert(obj2.name);
//”Nicholas”
//===========================================
var now = new Date();
When the Date constructor is used without any arguments, the created object is assigned the current date and time.
//===========================================
函数
函数传参
如果是类,则是引用传递。
function factorial(num){
if (num <= 1) {
return 1;
} else {
return num * factorial(num-1)
}
}
等价于
function factorial(num){
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num-1)
}
}
//============================================
类
创建方法:
1
var person = new Object();
person.name = “Nicholas”;
person.age = 29;
person.job = “Software Engineer”;
person.sayName = function(){
alert(this.name);
};
2 function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var person1 = createPerson(“Nicholas”, 29, “Software Engineer”);
var person2 = createPerson(“Greg”, 27, “Doctor”);
3
function Person(name, age, job){
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”);
4
Person = {
name: ''.
age:'',
job:'',
sayName: function() {
alert(this.name);
}
};
function Person() {
}
Person1 = new Person();
Person2 = new Person();
两个新建的实例在创建的时候,会自动包含一个__proto__的变量,这个变量指向Person的prototype,而Person的prototype是指向其Prototype。也就是说__proto__都是指向同一个Person的prototype。那么可以这么说,__proto__是类的Prototype和实例之间的一个链接,可以认为是一个引用。如果有c++的基础,我觉得可以把js的prototype看成是类的公有静态成员变量。
如果prototype的内容的不可更改的,但如果你进行了更改操作,其实这个更改操作不是对prototype进行的,而是对类的实例。
比如
person1 = new Person();
person2 = new Person();
person1.name = "My"; //为实例新建了一个name的变量,因为js的类是动态类型,所以这个是可以做到的。
alert(person1.name); //My for instance
alert(person2.name); //Nicholas for prototype
delete:删除实例的属性
delete person1.name
Methods:
hasOwnerProperty(arg): 判断实例是否含有某属性,不包含prototype中的属性,仅属于实例的。
in:判断实例是否含有某属性,包含prototype中的属性。
prototype的literally声明
Person.prototype = {
// constructor: Person,name : “Nicholas”,
age : 29,
job : “Software Engineer”,
sayName : function () {
alert(this.name);
}
};
此时prototype是覆盖了默认的prototype,所以没有了指向Person的constructor。在new的时候,会再自动添加prototype的constructor,但这时prototype的constructor指向的是Object。如果想要它指向的是Person,就需要在上面的声明中添加注释掉的代码。
继承:基本都有不完善的地方。
1 prototype chaining
2 constructor stealing
3 组合继承
4 Prototypal Inheritance
5 Parasitic Inheritance
1 通过prototype继承,形成prototype chaining。不好:如果父类含有引用类型,就变成就公有静态变量。
function SuperType(){
this.colors = [“red”, “blue”, “green”];
}
function SubType(){
}
//inherit from SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push(“black”);
alert(instance1.colors);
//”red,blue,green,black”
var instance2 = new SubType();
alert(instance2.colors);
//”red,blue,green,black”
2 constructor stealing。不好:会导致无法使用父类的prototype,而且方法需要写在父类的构造函数里面。
function SuperType(name){
this.name = name;
}
function SubType(){
//inherit from SuperType passing in an argument
SuperType.call(this, “Nicholas”);
//instance property
this.age = 29;
}
var instance = new SubType();
alert(instance.name);
//”Nicholas”;
alert(instance.age);
//29
3 组合继承:prototype chaining + constructor stealing。比较普遍被使用的方法
不好:调用两次父类的constructor(构造函数)
function SuperType(name){
this.name = name;
this.colors = [“red”, “blue”, “green”];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
//inherit properties
SuperType.call(this, name);
this.age = age;
}
//inherit methods
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function(){
alert(this.age);
};
var instance1 = new SubType(“Nicholas”, 29);
instance1.colors.push(“black”);
alert(instance1.colors); //”red,blue,green,black”
instance1.sayName();
//”Nicholas”;
instance1.sayAge();
//29
var instance2 = new SubType(“Greg”, 27);
alert(instance2.colors); //”red,blue,green”
instance2.sayName();
//”Greg”;
instance2.sayAge();
//27
4 Prototypal Inheritancefunction object(o){
function F(){}
F.prototype = o;
return new F();
}
5 Parasitic Inheritance,避免了组合继承的两次调用父类构造函数的问题。
function inheritPrototype(subType, superType){
var prototype = object(superType.prototype); //clone prototype
prototype.constructor = subType;
subType.prototype = prototype;
}
function SuperType(name){
this.name = name;
this.colors = [“red”, “blue”, “green”];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function(){
alert(this.age);
};
闭包
function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(){
return i;
};
}
return result;
}
返回的数组的值都是10,因为在函数里,它们都是赋值为i,只有一个i!而i最后会变成10。
使用闭包:
function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(num){
return function(){
return num;
};
}(i);
}
return result;
}
声明匿名函数后立即调用。
var name = “The Window”;
var object = {
name : “My Object”,
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
//”The Window”
由于函数的两个参数,this和arguments。外部函数的this执行的是object,由于函数的this是默认执行window,所以当内部函数被调用,那么它指向的就是全局的window,因为它是作为外部函数一个普通函数调用。that模式解决:
var name = “The Window”;
var object = {
name : “My Object”,
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()());
//”My Object”
闭包的问题:会比较消耗内存,因为当外部函数执行完后,如果内部函数还在使用,那外部函数并不会从内存中删去。
模拟块作用域:
(function() {
//block code
})();
//=========================================
singleton 单例化
var singleton = {
name : value,
method : function () {
//method code here
}
};
var singleton = function {
var privateVal = 0;
function privateFunc() { return false; }
return {
prop: true,
publicFunc: function() {
privateVal++;
return privateFunc();
}
};
}();
可拓展的单例:
var singleton = function(){
//private variables and functions
var privateVariable = 10;
function privateFunction(){
return false;
}
//create object
var object = new CustomType();
//add privileged/public properties and methods
object.publicProperty = true;
object.publicMethod = function(){
privateVariable++;
return privateFunction();
};
//return the object
return object;
}();