@linux1s1s
2017-07-20T17:29:24.000000Z
字数 2956
阅读 1215
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);//0
mo.increment(1);
console.log(mo.value);//1
mo.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);//3
console.log(b);//7
console.log(c);//11
a += b + c;
};
console.log(a);//3
console.log(b);//5
try {
console.log(c);
} catch (e) {
console.log(e.name + ':' + e.message);//ReferenceError:c is not defined
}
bar();
console.log(a);//21
console.log(b);//5
try {
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
}
控制台结果