《javascript面向对象精要》总结(一)

关于数据类型

原始类型:boolean,number,string,null,undefined。基础知识就不赘述了,那如何鉴别这些基础类型呢?最好的方法是使用操作符typeof

console.log(typeof "string");
console.log(typeof 10);
//像这样的用法大家都很熟悉,值得注意的是,typeof null,返回的值是"object",这不是我们需要的,所以通常使用value === null来判断值是否为null(注意要使用‘===’,因为undefined==null返回true)。

原始封装类型:String,number,Boolean,不知道你有没有注意到,这些类型和引用类型一样的好用,有他们自己的属性和方法。

var name = "Shi Jun We";
var firstChar = name.charAt(0);
console.log(firstChar);    // "S"

//然后实际上背后发生了这些事情,相信不是很难理解

var name = "Shi Jun wei";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
console.log(firstChar);
//这种临时对象,只是在值被读取的时候创建。也可以手动创建原始封装类型的数据:
   var name = new String("Shi Jun We");
console.log(typeof name);    //"object"
var found = new Boolean(false);
if(found){
    console.log("Found");
}
//如果你测试了上面的代码,你会发现这样的问题的存在,所以尽量避免这么做。

引用类型:Array,object。引用值是引用类型的实例,引用值就是对象,是一个属性和方法的无序列表。

var object = new Object();
var object = {};

var object2 = object;
object2 = null;

var array = [];
var method = "push";
array[method](12345);

要解除一个对象的引用,,只需要把这个变量的值改成null即可。


关于函数

Javascript函数其实就是一个对象,使函数不同于其他对象的决定特点就是函数存在一个被称为[[call]]的内部属性,typeof会查找这个属性,如果找到回返回function。内部属性是无法通过代码访问的,而是定义了代码执行时的行为。ECMAScript为JavaScript的对象的对象定义了多种内部属性,这些内部属性都用双括号标注。

//你可以尝试如下代码:
var found = new Boolean(false);
console.log(found);        // Boolean {[[PrimitiveValue]]: false}

函数的声明方式有两种,之前的文章有介绍过,这里就不赘述了。

参数对于函数来讲是非常重要,你可以给函数传递任意个数的参数却不造成错误。函数的实际参数保存在arguments的类似数组的对象中。函数的命名参数是为了方便,而不是为了限制参数的个数。

函数期望的(定义的)参数个数保存在函数的length属性中,无论你是以那种方式声明的函数。

var abc = function(a,b,c){};
console.log(abc.length);    // 3

因此,javascript中是不存在重载的,但是我们也可以根据传入的参数来选择不同的行为。可以通过参数的个数(arguments.length)或者判断命名参数是否为undefined来实现。

this我们都已经很熟悉了,javascript所有函数作用域内都有一个this对象代表调用该函数的对象。在全局作用域中,this就代表全局对象window了。至于改变this指向的方法,常用的call(),apply()这里就不多说了,我们来说一下bind()方法:

//bind()的第一个参数是传递给函数的this值,其他所有参数代表需要被永久设置在函数中的命名参数
function sayNameForAll(label){
    console.log(label+':'+this.name);
}

var person1 = {
    name:"Shi"
};
var person2 = {
    name:"Grey"
};

var sayNameForPerson1 = sayNameForAll.bind(person1);
sayNameForPerson1("person1");    // "person1:Shi"

//sayNameForPerson2不仅绑定this为person2,同时也绑定了一个参数为“person2”
var sayNameForPerson2 = sayNameForAll.bind(person2,"person2");
sayNameForPerson2();    // "person2:Grey"