@linux1s1s
2017-07-20T09:29:24.000000Z
字数 2956
阅读 1498
JavaScript 2017-07
记录一下 JavaScript语言精粹前四章的笔记
/**对象字面量,这个时候就已经生成了mo对象,而且这个对象已经完成了实例化,该实例具有成员变量value和成员方法increament方法*/var mo = {value: 0,//变量(类似Java中的成员变量)increment: function (inc) { //方法(类似Java中的成员方法)this.value += typeof inc === 'number' ? inc : 0;}};function onTableClick(event) {/**Immutable JS的字符串类型等同于Java的String类型*/var isEqual = 'c' + 'a' + 't' === 'cat';console.log(isEqual);//true/**直接使用mo变量,可以直接使用其中的成员变量和成员方法*/console.log(mo.value);//0mo.increment(1);console.log(mo.value);//1mo.increment(2);console.log(mo.value);//3/** 给对象mo增加一个方法* 所以这里需要提前赋值,* 将外部函数的上下文环境赋值为that,* 然后在内部函数中就可以直接获取外部函数的上下文环境了*//*另外这里也表明了在JS中函數可以拥有方法*/mo.double = function () {var that = this;/**这里的this即为外部函数double的上下文,也就是在对象mo的上下文中。因为在内部函数helper中再用this已经不再指向外部函数double的上下文了*/var helper = function () {that.value += that.value;};helper();//函数调用模式};mo.double();//方法调用模式console.log(mo.value); //6/**如果不按照上面這樣處理,結果就完全不符合預期了*/mo.doubleM = function () {var helper = function () {this.value += this.value;};helper();//函数调用模式};mo.doubleM();//方法调用模式console.log(mo.value);//6(而不是12,doubleM()函数字面量并没有任何作用,this.value = undefined)/**JS本质上是基于原型继承语言,所以和传统基于类继承语言有很大不同。不过由于JS缺乏自信,所以也提供了类似传统类继承的语法糖需要注意的是变量首字符请大写*/var Que = function (status) {this.status = status;};Que.prototype.getStatus = function () {return this.status;};var myQue = new Que("Running");//构造器调用模式(这种语法糖,Douglas Crokford 大神比较鄙视这么使用)console.log(myQue.getStatus());//Running/** 因为JS是一门函数式面向对象的编程语言,所以函数可以拥有方法,另外这里的函数和方法和Java/C++的函数和方法有很大不同*/var add = function (sum1, sum2) {return sum1 + sum2;};var array = [3, 4];//数组字面量var sum = add.apply(this, array);//Apply调用模式console.log(sum);//7/**so 并没有继承自Que.prototype,但我们可以在so对象上调用getStatus方法*/var so = {status: 'From so Object'};var status = Que.prototype.getStatus.apply(so);console.log(status);//From so Object/**JS是原型继承,所以具有天然的动态本质,新的方法会被立刻赋予到所有对象上,即时该对象已经实例化完成。* 所以我们可以尽情的扩展功能,这里对Function.prototype增加方法*/Function.prototype.method = function (name, func) {if (!this.prototype[name]) {this.prototype[name] = func;}return this;//任何函数总会有个返回值,如果没有指定返回值,则返回undefined。};Number.method('integer', function () {return Math[this < 0 ? 'ceil' : 'floor'](this);//小于0 使用Math.ceil,大于0 使用Math.floor});console.log((-10 / 3).integer());//-3(舍弃掉小数点后面的数字)/**作用域*//**此处完全不同于传统语言Java/C++中的块级作用域* 在JS中没有块级作用域,对应的是函数作用域,在函数中任何位置定义的变量,在该函数内部任何地方都可见* 而且在绝大数的语言中建议尽可能的延迟申明变量,而在JS中则相反,推荐申明在函数的顶部位置*/var foo = function () {var a = 3;var b = 5;var bar = function () {var b = 7;var c = 11;console.log(a);//3console.log(b);//7console.log(c);//11a += b + c;};console.log(a);//3console.log(b);//5try {console.log(c);} catch (e) {console.log(e.name + ':' + e.message);//ReferenceError:c is not defined}bar();console.log(a);//21console.log(b);//5try {console.log(c);//ReferenceError:c is not defined} catch (e) {console.log(e.name + ':' + e.message);}};foo();/**闭包*//**上面说的作用域貌似完全另类,不过JS中的作用域有个非常美妙的用处,因为内部函数可以访问外部函数的所有参数和变量(this和arguments除外)* 而且内部函数拥有比外部函数更长的生命周期,因为内部函数持有外部函数的上下文(有点类似于Java的内部类)* 我们修改最上面的对象字面量如下*/var moRe = (function () {var value = 0;return {increment: function (inc) {value += inc < 0 ? 0 : inc;},getValue: function () {return value;}};}());moRe.increment(200);console.log(moRe.getValue());//200}
控制台结果

