JavaScript 语言精粹的笔记

来源:互联网 发布:手机nfc读卡器软件 编辑:程序博客网 时间:2024/05/22 13:57

在JavaScrpit中,false、null、undefined、空字符串,0及NaN返回的都是false.

JavaScript中的常量有数字,字符串,对象,数组,方法,正则表达式。数组,方法,正则表达式都是对象。

在JavaScript中,对象被看做属性的容器,属性由键值对组成,其中键为字符串,值能为除了undefined之外的任意值。

JavaScript中对象定义的方法,其中fist name和last name的双引号是可选的:

var empty_object = {}var stooge = {    "fist name" : "Qiushi",    "last name" : "Li"};
或者可以嵌套定义:

var address = {    country : "China",     city : "Chongqing",     localtion : {        streetname : "Longhu Xilu",         name : "longhu garden"    }};

这时有两种方法可以提取对象里的属性:

1. address.localtion.name2. address["localtion"]["name"]
对象里的属性可以改变,方法如下:

1. address.localtion.name = "JinKe Garden"2. address["localtion"]["name"] = "Donghe Chuntian"
在JavaScript中,对象传递的时候,实际传递的是对对象的引用,例子如下:

var x = address;x.localtion.name; // Donghe Chuntianx.localtion.streetname = "Love Road";address.localtion.streetname // love road
值得一提的是,所有的空对象都指向同一个JavaScript内置空对象的引用。


typeof可以用来查看属性的类型,如下:

function MyObject(){}var obj1 = new MyObject()typeof obj1  //  "object"typeof MyObject  //  "function"var number = 1typeof number  //  "number"var string1 = "this is a string"typeof string1  //  "string"

同时hasOwnProperty可以用来一个对象是否有某个属性,但prototype的属性并不被算入其中,如下:

function MyObject(){}MyObject.prototype.x = 1;MyObject.y = 2;MyObject.hasOwnProperty('x')  // falseMyObject.hasOwnProperty('y')  // true


delete用于删除对象上的属性,包括prototype属性,如下:

function Person(){}Person.prototype.nationality = "china"Person.name = "qiushi"var realPerson = new Person()delete Person.prototype.nationalityrealPerson.nationality  // undefined

在JavaScript中,所有创建出来的东西都是全局可用的,所以,为了适当的信息隐藏,可以采用如下方法,首先建立一个对象,把所有的新建的东西全部放到对象中去作为对象的一部分,提高了可读性,避免了全局数据造成的不利后果。


自己对prototype的理解:prototype是JavaScript中用于实习继承或者信息重用的东西,在JavaScript中,所有的东西都继承自Object对象,其中Function对象也不例外。当我们自己去新建一个function的时候,这个新建的方法就是Function对象的实例,如下:

function testFunction(){}typeof testFunction   // "function"
我们再次去看Function对象中的属性可以发现,有很多固有的非prototype属性及prototype属性,这些属性想必都是定义在Object对象中的。所有当我们新建一个方法的时候,这些非prototype和prototype属性都随之继承了下来。

JavaScript中的调用共有四种模式:方法调用模式,函数调用模式,构造函数调用模式,apply调用模式。每个函数被调用的时候系统会向其传入两个值,分别为this和arguments,其中arguments是作为一种数组传过去的。所以有时候并不需要专门为函数编写参数,在函数内部即可直接使用调用该函数传进来的参数。四种模式的调用的区别在于在函数或方法体内this的指向,即this在被传入函数或方法体之前被初始话为什么。(p.s. 当一个函数在一个对象中作为一个属性存在时,我们通常称它为方法)。构造函数调用即new一个对象出来,然后通过这个对象来调用其中的prototype和非prototype方法。apply调用模式的作用是把一个对象中定义的方法应用到另一个对象中去,即一个对象能通过apply调用模式来调用其本身没有定义的方法,代码如下:

var MyObject = function (info) { this.status = info}MyObject.prototype.getStatus = function () { return this.status }var status1 = new MyObject("this is a status")console.log(status1.getStatuts()) // this is a statusvar anotherStatus = { status : "this is another status" }var status2 = MyObject.prototype.getStatus.apply(anotherStatus)console.log(status2)  // this is another status
apply的意思是应用,即把这个对象中的方法应用到另一个对象中去,实现了代码的复用。此处的apply中的参数即使MyObject的getStatus方法里的this,通过这个参数改变了this的指向。apply通常有2个参数,第一个是this,用于改变this的指向,第二个是arguments,用于想方法传参。apply也能同时应用多个方法(prototype和非prototype皆可)到一个新对象上去,代码如下:

MyObject.addStatusToInfo = function () { return this.status + " || status been added" }var status3 = MyObject.prototype.getStatus.apply(AnotherStatus)var status3 = MyObject.addStatusToInfo.apply(AnotherStatus)console.log(status3)  // this is another status || status been added


JavaScript是一门原型继承的语言,意味着能直接重其他对象继承属性。方法的调用总是有返回值,如果没有显式指定返回值,则undefined会被返回。当一个对象通过函数被new出来时,该函数的返回值是this,即对象本身,此时赋予了new出来的对象对该对象内部属性的访问权限。



var quo = function (status) {return { getStatus : function () {return status;}}};

var test = quo("amazing");

console.log(test.getStatus()); // amazing

此处可以不用new一个对象而直接使用,因为返回值本身就是一个对象。

在上面这个例子中,第一步返回的是一个对象。当执行完第二步以后,test指向quo返回回来的那个对象,即一个内部逻辑为getStatus方法的对象。test指向的对象的getStatus方法依旧能访问调用quo时传递给其的status属性(即"amazing")尽管对象已经被返回了,这是因为getStatus方法能访问创造其的环境的上下文,这就是闭包。


var myObject = function () {

var value = 0; 

return {increment : function (val) {value += val;}, getStatus : function() {return value;}}}

注意,在increment方法里的value不能写成this.value。因为如果那样写,this指的是调用包含increment和getStatus方法的对象,而那个对象里并没有申明value属性,所以此处会是NaN。


var myObject = function () {

var value = 8; 

return {increment : function (val) {value += val;}, getStatus : function() {return value;}}}();

这里与上个例子唯一不同的是最后的一对括号(),它的意思是返回一个对象的同时调用了这个对象,即相当于new了一个对象,名叫myObject,此时就能直接调用对象里面的方法了。如myObject.increment(9);然后myObject.getStatus(),得到的结果是17.如果试图去像以前那样new一个方法当做对象使用的话,会被提示TypeError: object is not a function错误,因为myObject已经是一个对象,不能再新建了。


继承:

在JavaScript中,继承是通过一个对象直接继承另一个对象来实现的。当一个方法对象创建的时候(例如:var test = function(){}),Function会自动执行如下语句:this.prototype = {constructor : this}。这句话的意思是给新建的方法对象一个prototype属性,属性的内容是一个对象,此对象的意义在于指定由这个方法对象new出来的对象的构造函数,意思是构造函数即是方法对象本身,例如:

var test = function (a, b) {var sum = 0; sum += a + b; return sum;}

var newObject = new test(3,4)

console.log(newObject.constructor) //  function (a, b) {var sum = 0; sum += a + b; return sum;}

或者我们也能直接来查看方法对象的构造函数:

console.log(test.prototype.constructor) //  function (a, b) {var sum = 0; sum += a + b; return sum;}

重上面这个例子就能看出,一个对象的prototype属性能存放一个对象,这就是JavaScript中继承的常用方法,即将重其他类中继承来的特性放在prototype对象中。



console.log({}) // Object

Object.create(anotherReference) // 用处创造一个对象的复制品


function Batman() { function useBelt(){return "this is a test";} this.shout = function(){return useBelt();}}

function afterLunch() {this.eat = function(func){return func()};}

var test = new afterLunch();

var theBatman = new Batman();

test.eat(theBatman.shout); // this is a test



JavaScript中对象是以键值对的形式出现的,键是String,值可以为各种类型。如果值是一个函数,我们通常叫他方法。当一个对象中的方法被调用的时候,this指的就是这个对象,


--------------------------------------------------------------------------------------------------


JavaScript中有的封装表现为在函数内部定义变量或者方法,这样在函数外面就不能调用这些属性或方法,如下:

var myConstructor = function () { var age = 24; function alertage () { alert (age); } this.name = "qiushi";}

var testConstructor = new myConstructor()

testConstructor.age // undefined

testConstructor.alertage() // TypeError: Object [object Object] has no method 'alertAge'


如果我想要自己的名字能被外部看到,但不想暴露自己的年龄,通过下面这种方式能实现:

var myConstructor = function () { var age = 24; function alertage () { alert (age); } this.name = "qiushi"; this.alertName = function () { alert (this.name); } this.alertFullInfo = function () { alert ("name : " + this.name + " age : " + age); } }


var testConstructor = new myConstructor()

testConstructor.alertName()

testConstructor.alertFullInfo()

以上均能正确地弹出信息。同时注意到有的方法前面有this有的没有,这是JavaScript中的另一种封装,即特权方法。它在函数内部定义,却能在函数外部被调用,同时也能调用函数内部的私有属性。这就是它“特权”的含义。

Patterns

Public

function Constructor(...) {

this.membername = value;

}
Constructor.prototype.membername = value;

Private

function Constructor(...) {

var that = this;

var membername = value;

function membername(...) {...}

}

Note: The function statement

function membername(...) {...}

is shorthand for

var membername = function membername(...) {...};

Privileged

function Constructor(...) {

this.membername = function (...) {...};

}


----------------------------------------------------------------------------------------------------


有时候,当一个方法参数太多的时候,很难记住第几个参数对应的是什么,这时可以使用如下方式去传参:

var myObject = maker({firstname:f,lastname:l,sex:a})相对于使用传统的var myObject = maker(f,l,a).这样不需要记住参数的特定位置,而是直接传递对象。


在Javascript中,可以通过返回对象的方式来隐藏信息。如

var animal = function(){var dog = {}; dog.sex = male; dog.size = big; return dog;}


----------------------------------------------------------------------------------------------------

typeof null的输出结果是object。typeof NaN的结果居然是number

在JavaScript中,对象永远不可能为空值,因为它至少会从Object对象中继承prototype属性


JavaScript中==和===的区别在与,前者只在符号两边的操作数类型相同的时候才起作用,例如 0 == 0 //true,而在 0 == “”上也为true,显然是错误的。===是在符号两边的操作数相等且类型相同的情况下才为true,即一般的严格相等。建议是尽量使用===。


在JavaScript中,随时应该牢记的是,方法就是数值。e.g. var foo = function fun(){};


在函数后面加上一对括号表示执行该函数,例如function foo(){ console.log("this is a test")}(); // this is a test

----------------------------------------------------------------------------------------------------

JavaScript数组:


JavaScript自身也对对象和数组的区别比较模糊,因为你使用var testArray = []; typeof testArray //object。为了分清楚你使用的到底是数组还是对象,我们可以自定义一个方法,例如:

var is_array = function (value) {

    return value &&

        typeof value === 'object' &&

        typeof value.length === 'number' &&

        typeof value.splice === 'function' &&

        !(value.propertyIsEnumerable('length')); 

};


首先检查valu不为空,其次其为object,然后长度为number,然后value要拥有一个splice的方法,最后value的长度不可枚举。