笔记:《JavaScript面向对象精要》-第1、2章

一、原始类型和引用类型

1.1 对象的两种类型:
JavaScript使用一个变量对象追踪变量的生存期。 原始类型保存为简单的值, 引用类型则保存为对象,其本质是指向内存位置的引用。

1.2 原始类型
1..2.1 五种原始类型:
Boolean
Number
String
Null
Undefined

1.2.2 鉴别原始类型
使用typeof 操作符
console.log(typeof 10);  //"number"
console.log(typeof “123”);  //“string” 
console.log(typeof true);  //"boolean"
console.log(typeof undefined);  //"undefined"

//null为特例,可通过和null值进行比较判断
console.log(typeof null);  //"object"
console.log(value===null);  //true or false

1.3 引用类型:
1.3.1创建对象(实例化对象)
使用new操作符
var object = new Object();
该代码实例化了一个通用对象,并将它的引用保存在object中。object变量实际上并不保存对象的实例,而是一个指向内存中实际对象所在位置的指针(或者说引用)。

1.3.2 引用对象解除
解除引用的最佳手段是将对象变量置为null。在不使用对象时将其引用解除,会让垃圾收集器对那块内存进行释放。
var object1 = new Object();
//doing something

object = null;

1.3.3 六种内建类型:
Object
Array
Function
Date
RegExp
Error

内建类型实例化
使用new操作符来实例化每一个内建引用类型:
var object = new Object();
var items = new Array();
var func = new Function("console.log('hi');");   //称为构造函数
var now = new Date();
var re = new RegExp("\\d+");
var error = new Error("something bad happened.");
字面形式,字面形式允许不使用new操作符和构造函数显示创建对象的情况下生成引用值。
//对象字面形式
var person = {
    name:"liang",
    sayName:function(){
        return this.name;
    }
};
person.year = 1992;  //添加对象的属性

var items = ["item1","item2","item3"];

//函数字面形式,函数声明
function func(value){
    return value;
}

//函数字面形式,函数表达式(匿名函数)
var func = function(){
    statement;
};

//正则表达式字面形式
var numbers = /\d+/g;

1.3.4 访问属性
var array = [];
array.push(123);  //使用点号

array["push"](456);  //使用中括号

//中括号允许使用动态访问方法
var method = "push";  
array[method](789);
点号更易读,但使用中括号可允许你在属性名字上使用特殊字符。

1.3.5 鉴别引用类型
对于函数,typeof 操作符返回“function”;
其他非函数的引用类型,typeof 操作符都返回“object”。因此,使用instanceof 操作符来区分其他引用类型。
instanceof 操作符以一个对象和一个构造函数为参数。如果对象是构造函数所指定的类型的一个实例,instanceof 返回true;否则返回false。
var items = [];
var object = {};

function reflect(){
    return value;
}

console.log(typeof reflect);   //"function"

console.log(items instanceof Array);   //true
console.log(object instanceof Object);   //true
console.log(reflect instanceof Function);   //true

//这些引用类型也都是Object的实例,instanceof 操作符可鉴别继承类型。
console.log(items instanceof Object);   //true
console.log(reflect instanceof Object);   //true

1.3.6 鉴别数组
instanceof 可以鉴别数组,但有一个例外,当你把一个数组从一个框架传到另一个框架时,instanceof 就无法识别,因为这个数组是来自不同框架的Array的实例。
使用Array.isArray()鉴别数组,IE8及更早版本不支持。
var items = [];

console.log(Aray.isArray(items));   //true

1.4 原始封装类型
原始封装类型共有3种(String, Number 和 Boolean)。
当读取字符串、数字或布尔值时,原始封装类型将被自动创建。这种特殊引用类型的存在使得原始类型用起来和对象一样方便。
//第二行代码把name当成一个对象,调用了charAt方法
var name = "liang";
var firstChar = name.charAt(0);
console.log(firstChar);   //"l"

/*
背后的工作原理:创建了一个临时对象,随后被销毁
var name = "liang";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
console.log(firstChar);   //"l"
*/

//临时对象仅在值被读取时创建,instanceof并没有真的读取任何东西,因此为false
console.log(typeof name);   //string
console.log(name instanceof String);   //false


二、函数

函数其实就是对象。使函数不同于其他对象的决定性特点是函数存在一个被称为[[call]]的内部属性。
内部属性无法通过代码访问,它定义了代码执行时的行为。
[[call]]是函数独有的,表明该对象可以被执行。

2.1 声明还是表达式
函数有两种字面形式。第一种以function关键字开头,后面跟着函数的名字。第二种是函数表达式,function后面不需要跟着函数名,这种函数被称为匿名函数。
//函数声明
function add(num1,num2){
    return num1 + num2;
}

//函数表达式
var push = function(num1,num2){
    return num1 + num2;
};
两者中最重要的区别是,函数声明会被提升至上下文的顶部。意味着可以先使用函数,后声明。
而函数表达式是通过变量引用,因此无法提升。
var sum = add(3,5);

function add(num1,num2){
    return num1 + num2;
}

2.2 函数就是值
记住函数就是对象,可以将函数当成参数传递给其他的函数。
比如数组的sort()方法,接受一个比较函数作为可选参数。
在默认情况下,sort()将数组中每个对象转换成字符串然后进行比较。
var numbers = [1,6,3,7,2,10];
numbers.sort(function(num1,num2){
    return num1 - num2;
});

console.log(numbers);   //[1, 2, 3, 6, 7, 10]
numbers.sort();
console.log(numbers);   //[1, 10, 2, 3, 6, 7]

2.3 参数
函数参数实际上被保存在一个被称为arguments类似于数组的对象中。
var reflect = function(){
    return arguments[1];
};

console.log(reflect("first","second"));   //second
console.log(reflect.length);    //"0"
应尽量避免使用argument。不过,在某些情况下使用arguments比名称参数有效。例如,创建一个函数,可以接受任意数量的参数,并返回它们的和。
function sum(){
    var i = 0,
        result = 0,
        len = arguments.length;
    
    while (i < len){
        result += arguments[i];
        i++;
    }
    return result;
}

console.log(sum(3,5,1));      //9
console.log(sum(1,2,3,4));    //10
console.log(sum());   //0
//由于result的初始值为0,改函数就算没有参数也能正常工作

2.4 重载
大多数面向对象语言支持函数重载,它能让一个函数具有多个签名。
函数签名由函数的名字、参数的个数及其类型组成。
JavaScript并没有签名,但可以模仿函数重载。用arguments对象获取传入的参数个数并决定怎么处理。
function sayMessage(message){
    if (arguments.length === 0){
        message = "Default message";
    }
    
    console.log(message);
}

sayMessage("Hello");   //Hello
sayMessage();    //Default message

2.5 对象方法
对象的属性的值是函数,则该属性被称为方法。
2.5.1 this对象
JavaScript所有函数作用域内都有一个this对象代表调用该函数的对象。在全局作用域中,代表全局对象。
function sayNameForAll(){
    console.log(this.name);
}

var person1 = {
    name: "liang",
    sayName: sayNameForAll
};

var person2= {
    name: "zhu",
    sayName: sayNameForAll
};

person1.sayName();    //liang
person2.sayName();    //zhu

2.5.2 改变this
call() 方法
call() 的第一个参数指定了函数执行时this的值,其后的所有参数(可选)都是需要被传入函数的参数。
function sayNameForAll(){
    console.log(this.name);
}

function sayName(a){
    console.log(a + ": "+this.name);
}

var person1= {
     name: "liang"
};

var person2= {
    name: "zhu"
}

sayNameForAll.call(person1);    //liang
sayName.call(person1,"name");    //name: liang

apply() 方法
apply() 方法的工作方式和call()完全一样,但它只接受两个参数:this的值、一个数组(或者类似数组的对象,内含需要被传入函数的参数)。
function sayNameForAll(a){
    console.log(a + ": " + this.name);
}

var person1 = {
    name: "liang"
};

var person2 = {
    name: "zhu"
};


sayNameForAll.apply(person1,["person"]);  //person: liang

var array = [1,2,3,4];
sayNameForAll.apply(person2,array);   //1: zhu
sayNameForAll.apply(person2,array[2]);  // error

bind() 方法
bind() 的第一个参数是要传给新函数的this的值。其他所有参数代表需要被永久设置在新函数中的命名参数。可以在之后继续设置任何非永久参数。
function sayName(a){
    console.log(a + ": " + this.name);
}

var person1 = {
    name: "liang"
};

var person2= {
    name: "zhu"
};

//绑定this,并传入参数
var sayPerson1 = sayName.bind(person1,"person");
sayPerson1();   //person: liang

//仅绑定this
var sayPerson2 = sayName.bind(person2);
sayPerson2();   //undefined: zhu
sayPerson2("person");   //person: zhu



猜你喜欢

转载自blog.csdn.net/kjhz_liang/article/details/80438569