虽然说用JS很多年了,但是却一直停留在肤浅的阶段,对JS的机制原理依然是一知半解,例如:闭包,虽然能说出一二,却不能说出三四,确实惭愧。最近恶补一番,并将比较与大家分享,希望对大家有些帮助。


 


闭包

老概念,在JS编程中我们可能在不经意间就用到了它,只是我们不知道而已。首先呢,闭包并不是一个函数或者类型,而是一直语言机制,如果硬要做个类比的话,我觉得它应该属于“继承”这类型的语言机制。

在JS里面,函数外部是不能直接调用函数内部的变量,如果我们非要调用它们的话,那你就需要闭包,举个例子:

如果我们想在outerFunc外部调用color变量,那我们就得使用闭包机制,调用方式如下

 

  1. function outerFunc()
  2. {
  3. var color='red';
  4. function innerFunc(c)
  5. {
  6. color=c;
  7. alert(color);
  8. }
  9. return innerFunc();
  10. }
  11. var tmp=outerFunc();
  12. tmp('green'); //green



 

 


 

This

如果我们调用的对象分别存在多个定义域里面,例如:全局或局部,并且我们在用它的时候还加上了This关键字,那大家就要小心了,这时候我们就需要分辨我们调用的对象到底是全局的呢,还是局部的呢?

第一次调用返回的结果是一个包含this.name的函数体,但是我们执行它的定义域确实在全局,所有它会返回’the window'。但是第二次调用呢,它的定义域是局部,所以它返回'my object',第三次调用返回的是闭包,所以它的结果当然是它的局部变量值‘my object2'。

 

  1. var name = "The Window";
  2. var object = {
  3. name: "My Object",
  4. getNameFunc: function () {
  5. return function () {
  6. return this.name;
  7. };
  8. }
  9. };
  10. var object2 = {
  11. name: "My Object2",
  12. age: 22,
  13. gender:'Femal',
  14. getNameFunc: function () {
  15. var name = this.name;
  16. return function () {
  17. return name;
  18. };
  19. }
  20. };
  21. alert(object.getNameFunc()());
  22. object.show = object.getNameFunc();
  23. alert(object.show());
  24. alert(object2.getNameFunc()());



 

 


 

Call 和 Apply

这两关键字的使用和This有很大的关系,它们能模拟对象的执行环节,对上面的例子来说,如果我们对第一调用做如下修改,那么它返回的结果将是’My Object‘。

 

  1. alert(object.getNameFunc().call(object));
  2. alert(object.getNameFunc().apply(object));

首先呢,object.getNameFunc()返回的是一个函数体,其次呢,我们通过call和apply在object的定义域内执行返回的函数体,所以返回的值也就不一样了。

 

Prototype

prototype是JS对象的一个内部原型机制,我们可以给它添加属性或方法,这些内容都能被它对应的对象所识别。prototype在JS面向对象的编程中用的比较多,基本上都用它来实现对象的继承机制,具体看下面例子。

  1. function person()
  2. {
  3. this.sex = 'male';
  4. this.age = 21;
  5. }
  6. person.prototype.introduce = function () {
  7. console.log('im a ' + this.sex + ' and im ' + this.age + ' years old');
  8. }
  9. function Jim()
  10. {
  11. this.name = 'Jim';
  12. }
  13. Jim.prototype = new person();
  14. var people = new Jim();
  15. people.introduce();


 

 

在这里呢,我们成功的将person的所有属性赋值给Jim.prototype了,当然这些东西对Jim对象是完全可见的,大家看,是不是通过这种方式很实现JS的单项继承呢?