一些简单的示例代码,都是自己写的,主要用于备忘,相关解释都在注释里
//==========================================================call_apply==============================================================//
var someuser = {
name: 'hb',
display: function(words) {
console.log(this.name + ' says ' + words);
}
};
var foo = {
name: 'foobar'
};
someuser.display.call(foo, 'hello');
//输出 foobar says hello
/*
call 和 apply 的功能是以不同的对象作为上下文来调用某个函数。
简而言之,就是允许一个对象去调用另一个对象
的成员函数。
*/
//=======================================================//
/*
每次都使用all或apply方法改变上下文,需要每次把上下文作为参数进行传递
使得代码狠凌乱,可以使用bind来永久绑定上下文。
*/
var someuser = {
name: 'hb',
func: function() {
console.log(this.name);
}
};
var foo = {
name: 'foobar'
};
foo.func = someuser.func;
foo.func();//输出 foobar
foo.func1 = someuser.func.bind(someuser);
foo.func1();//输出hb
func = someuser.func.bind(foo);
func();//输出 foobar
func2 = func;
func2();//输出 foobar
//========================================================//
//bind用于绑定参数表
var person = {
name: 'hb',
says: function(act, obj){
console.log(this.name + ' ' + act + ' ' + obj);
}
};
person.says('loves','hb');//输出 hb loves hb
hbLoves = person.says.bind(person, 'loves');
hbLoves('you');//输出 hb loves you
//======================================================callback====================================================================//
var EventEmitter = require('events').EventEmitter;
var event = new EventEmitter();
var name_g = 'HB';
var year_g = '2012';
// function sleep(milliSeconds) {
// var startTime = new Date().getTime();
// while (new Date().getTime() < startTime + milliSeconds);
// };
var jobdone = function(name, year){
console.log(name + ' are in year: ' + year);
};
var setYear = function(name, jobdone){
setTimeout(function(){
year_g = '2013';
name_g = 'Founder';
event.emit(jobdone);
}, 2000);
};
event.on(jobdone, function(){
jobdone(name_g, year_g);
});
console.log(name_g + ' are in year: ' + year_g);
setYear('Founder', jobdone);
console.log('All done!');
//======================================================closure=====================================================================//
var generateNoneClosure = function(){
var count = 0;
//函数内嵌套定义函数并调用,没有形成闭包。
//外部count不能被引用,得到结果均为undefied
function get(){
count++;
return count;
};
get();
};
var counter = generateNoneClosure();
// console.log(counter);
// console.log(counter);
//======================分割线===================================//
var generateClosure = function(){
var count = 0;
this.tmp = 1;
var get = function(){
count++;
return count;
};
console.log(this.tmp);//输出1
console.log(this.count);//输出undefied
return get;
//当函数返回一个内部定义的函数,则形成闭包,闭包包括被返回
//的函数,以及这个函数定义的环境。
};
generateClosure();
// var counter1 = generateClosure();
// var counter2 = generateClosure();
// console.log(counter1()); // 输出 1
// console.log(counter2()); // 输出 1
// console.log(counter1()); // 输出 2
// console.log(counter1()); // 输出 3
// console.log(counter2()); // 输出 2
//============================================================context===============================================================//
var someuser = {
name: 'hb',
display: function(){
console.log(this.name);
}
};
someuser.display();//输出 hb
var foo = {
bar: someuser.display,
name: 'foobar'
};
foo.bar();//输出 foobar
//其中的 this 指针不属于某个函数,而
//是函数调用时所属的对象
//=========================================================//
var someuser = {
name: 'byvoid',
func: function() {
console.log(this.name);
}
};
var foo = {
name: 'foobar'
};
someuser.func(); // 输出 byvoid
foo.func = someuser.func;
foo.func(); // 输出 foobar
name = 'global';
func = someuser.func;
func(); // 输出 global
/*
JavaScript 的函数作用域是静态的,也就是说一
个函数的可见范围是在预编译的语法分析中就可以确定的,而上下文对象则可以看作是静态
作用域的补充。
*/
//================================================prototype_inherit================================================================//
//构造函数
function Animal(name, type) {
this._name = name;
this._type = type;
};
//原型定义
Animal.prototype = {
name: this._name,
type: this._type,
jump: function() {
console.log(this._name + ' is jumping.');
},
eat: function() {
console.log(this._name + ' is eatting');
}
};
//var cat = new Animal('Kate','cat');
// cat.jump();
// cat.eat();
//=====================================================//
//继承原型
function Dog(){};
Dog.prototype = new Animal('Henry','dog');
// var dog = new Dog();
// dog.jump();
// dog.eat();
//=====================================================//
//实现多态(重写方法)
//_name = 'fuck';
Dog.prototype.jump = function() {
console.log('Hi, this is ' + this._name + ', I am jumping.');
};
//=====================================================//
//当需要为实例化对象添加单独的属性和方法
var dog = new Dog();
dog._name = 'Jack';
dog._type = "Labrador";
dog.shout = function() {
console.log('I am a ' + this._type + '.');
};
// dog.jump();
// dog.eat();
// dog.shout();
//=======================================================prototype==================================================================//
//原型生成对象
function Person() {
};
Person.prototype.name = 'hb';
Person.prototype.showName = function() {
console.log(this.name);
};
//==================================================//
function Foo() {
var innerVar = 'Hello';
this.prop1 = 'hb';
this.func1 = function() {
innerVar = '';
};
};
Foo.prototype.prop2 = 'Carbo';
Foo.prototype.func2 = function() {
console.log(this.prop2);
};
var foo1 = new Foo();
var foo2 = new Foo();
console.log(foo1.func1 == foo2.func1);//输出 falese
console.log(foo1.func2 == foo2.func2);//输出 true
//构造函数内定义的属性继承方式与原型不同,子对象需要显式调用父对象才能继承构
//造函数内定义的属性。
//构造函数内定义的任何属性,包括函数在内都会被重复创建,同一个构造函数产生的
//两个对象不共享实例。
//构造函数内定义的函数有运行时闭包的开销,因为构造函数内的局部变量对其中定义
//的函数来说也是可见的。
//====================================================//
//除非必须用构造函数闭包,否则尽量用原型定义成员函数,因为这样可以减少开销。
//尽量在构造函数内定义一般成员,尤其是对象或数组,因为用原型定义的成员是多个
//实例共享的。
//==========================================================scope================================================================//
if (true) {
var somevar = 'value';
}
console.log(somevar); // 输出 value,而不会出现变量为定义错误
/*
JavaScript 的作用域完全是由函数来决定的,if、for 语句中的花括号不是独
立的作用域。
*/
//=========================================================//
var scope = 'top';
var f1 = function() {
console.log(scope);
};
f1(); // 输出 top
var f2 = function() {
var scope = 'f2';
f1();
};
f2(); // 输出 top
/*
作用域的嵌套关系不是在调用时确定的,而是在定义时确定的。
*/