JavaScript读书笔记

[b]一. javascript基础[/b]
1. 使用同一个var语句定义的变量不必有相同的类型

var test="hi", age=25


2. 在使用变量之前不必声明,javascript的解释程序遇到未声明的标示符时,用该变量名创建一个全局变量,并将其初始化为指定的值。

var test = "hi"
test1 = test + "world"


3. javascript中的变量可以存放两种类型的值
a. 原始值,它们的值直接存储在变量访问的位置。一共有5种:Undefined, Null, Boolean, Number, String。
b. 引用值,存储在变量处的值是一个指针,指向存储对象的内存处。

4. Undefined类型
a. 当声明的变量未被初始化时,该变量的默认值是undefined。
b. 当函数无明确返回值时,返回的值也是undefined。

5. Null类型
undefined是从null派生出来的,所以null==undefined,但是它们的含义不同。undefined是声明了变量但未对其初始化时赋予该变量的值,null则用于表示尚未存在的对象。

var i;
alert(i == undefined); //true
alert(i == null); //true
alert(undefined == null); //true


6. toString方法
所有对象都有toString方法,可以用来转化自身的值为字符串。

7. parseInt方法
a. 该方法会转化字符串的部分值

var i1 = parseInt("blue"); //NaN
var i2 = parseInt("123blue"); //123

b. 如果十进制数包含前导0,则要使用基数10,否则有可能会以外得到八进制的值。

var i1 = parseInt("010"); //8
var i2 = parseInt("010", 8); //8
var i3 = parseInt("010", 10); //10


8. Number方法
该方法和parseInt不同,它会试着转化整个值

var i1 = Number("blue") //NaN
var i1 = Number("123blue") //NaN


9. typeof和instanceof
这两个运算符都用于指示变量的类型,但是typeof只返回5种值:undefined,boolean,number,string,object,其中若变量是引用类型或Null类型,则都返回object。这个时候要判断具体的类型就需要instanceof运算符了。

var o = new String("sss");
alert(typeof o); //object
alert(o instanceof String); //true

alert(typeof null); //object

var s = "sss";
alert(typeof s); //string
alert(s instanceof String); //false

//注意没有string类型,以下写法是错误的。
//alert(s instanceof string);


10. Object类
1. javascript中的所有类都由这个类继承而来。这个类有以下两个属性:
Constructor:对创建对象的函数的引用。
Prototype:对该对象的对象原型的引用。

11. Function类
Function类创建函数的语法如下:
var f = new Function(a1, a2, ... , an, function_body);
a1~an都是参数,最后一个是函数主体。
在ECMAScript中,函数名只是指向函数对象的引用值,行为就像其他指针一样。

function f1(v){
alert(v);
}
//以上函数用Function类重写
var f1 = new Function("v", "alert(v)");


[b]二. 对象基础[/b]
1. 声明和实例化
对象是用关键字new后跟要实例化的类的名字创建的

var o = new Object();
var s = new String();


2. 关键字this
a. 在构造方法中,this指向的是被new创建的对象。
b. 在普通方法中,this指向的是该方法所属的对象。

3. 定义类或对象
a. 工厂方式:因为“晚绑定”,对象的属性可以在对象创建后动态定义,所以可以这样:

function createCar(color, doors){
var tempCar = new Object();
tempCar.color = color;
tempCar.doors = doors;
tempCar.showColor = function(){
alert(this.color);
}
}

var car1 = createCar("red", 4);
var car2 = createCar("blue", 2);

b. 构造函数方式:使用new和this,在构造函数内部不创建对象,在外部调用new的时候,在执行构造函数的第一行前先创建一个对象,只有用this才能访问:

function Car(color, doors){
this.color = color;
this.doors = doors;
this.showColor = function(){
alert(this.color);
}
}

var car1 = new Car("red", 4);
var car2 = new Car("blue", 2);

c. 混合构造函数/原型方式
以上两种方式都有个问题,就是每次创建对象都会创建对象的方法,虽然可以把方法定义在构造函数外面,然后通过属性指向该方法,但是这种做法看起来不像对象的方法。所以还有一种构造函数使用原型方式来实现,但是纯原型方法又带来另外两个问题,1.无法在构造函数中指定参数;2.对于属性指向对象的情况会产生问题,因为对象是不能被多个实例共享的。由此出现了混合构造函数/原型方式,用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数:

function Car(color, doors){
this.color = color;
this.doors = doors;
this.drivers = new Array("smy", "zq");
}
Car.prototype.showColor = function(){
alert(this.showColor);
}

var car1 = new Car("red", 4);
var car2 = new Car("blue", 2);


4. 修改对象
可以用prototype属性为任何已有的类添加新方法或修改已有的方法。

Car.prototype.showColor = function(){
alert("this car's color is " + this.color);
}


5. 删除对象属性
可以使用delete是用来删除对象的某个属性

delete Car.color;


[b]三. 继承[/b]
1. 对象冒充
在使用构造函数来创建对象的过程中,this指向的是被new创建的对象。而在普通的方法调用中this指向的是该方法所属的对象,所以可以这样使用this:

function ClassA(color){
this.color = color;
this.sayColor = function(){
alert(this.color);
}
}

function ClassB(color, doors){
this.newMethod = ClassA;
this.newMethod(color);
delete this.newMethod;

this.doors = doors;
this.sayDoors = function(){
alert(this.doors);
}
}

var o = new ClassB("red", 2);
o.sayColor();
o.sayDoors();

以上有几点要注意:
1. 使用delete是为了避免在ClassB构造方法外部调用ClassA方法。
2. this.newMethod(color);绝对不能使用ClassA(color)代替,只有在前者中this会指向new ClassB("red", 2);创建的对象,而后者中this指向的将是windows。

2. call()和apply()方法
跟对象冒充类似,call和apply都是用指定的对象代替调用函数中的this对象,它们之间的不同在于apply使用了数组表示传递给调用函数的参数。

//使用call
function ClassB(color, doors){
ClassA.call(this, color);

this.doors = doors;
this.sayDoors = function(){
alert(this.doors);
}
}
//使用apply
function ClassB(color, doors){
ClassA.apply(this, arguments);

this.doors = doors;
this.sayDoors = function(){
alert(this.doors);
}
}


3. 原型链
prototype是对象的模板,prototype对象的任何属性和方法都被传递给那个类的所有实例。

function ClassA(){}

ClassA.prototype.color = "red";
ClassA.prototype.sayColor = function(){
alert(this.color);
}

function ClassB(){}

ClassB.prototype = new ClassA();
ClassB.prototype.doors = 4;
ClassB.prototype.sayDoors = function(){
alert(this.doors);
}

var o = new ClassB();
o.sayColor();
o.sayDoors();

原型链的本质是调用new ClassA()时创建一个ClassA对象,并把这个对象赋值给ClassB.prototype,这样ClassB的所有对象都有了ClassA对象的属性和方法。另外要注意的是子类的所有属性和方法必须出现在prototype属性被赋值之后,因为在它之前赋值的所有方法都会被删除。
使用这种方式构造的对象在调用instanceof运算符时,对ClassB的所有实例,对ClassA和ClassB对返回true;但是使用原型链方式构造的对象将带来和使用原型方式创建对象时的相同的问题:1.无法在构造函数中指定参数;2.对于属性指向对象的情况会产生问题,因为对象是不能被多个实例共享的。另外原型链不支持多重继承,因为原型链会用另一类型的对象重写prototype属性。

4. 混合对象冒充/原型链方式
用对象冒充继承构造函数的属性,用原型链继承prototype对象的方法。

function ClassA(color){
this.color = color;
}

ClassA.prototype.sayColor = function(){
alert(this.color);
}

function ClassB(color, doors){
ClassA.call(this, color);
this.doors = doors;
}

ClassB.prototype = new ClassA();
ClassB.prototype.sayDoors = function(){
alert(this.doors);
}

var o = new ClassB("red", 2);
o.sayColor();
o.sayDoors();

注意:执行以上的代码,color这个属性存在于ClassB.prototype中,而不存在于ClassA.prototype。可以试着在上述代码中把ClassB.prototype = new ClassA();替换成ClassB.prototype = new ClassA("red");

alert(ClassA.prototype.color); //undefined
alert(ClassB.prototype.color); //red
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值