查看: 1555|回复: 0

[JavaScript/JQuery] javascript高级程序设计(第3版)之 学习笔记

发表于 2018-3-17 08:00:01
Function 类型
  1. /*函数是对象,函数名是指针*/
  2. function sum(num1, num2){
  3. return num1 + num2;
  4. }
  5. alert(sum(10, 20)); // 20
  6. var anotherSum = sum; // 使用不带圆括号的函数名是访问函数指针,而非调用函数
  7. alert(anotherSum(10, 10); // 20
  8. sum = null;
  9. alert(anotherSum(10, 10)); // 20
  10. // ==========
  11. /*函数声明与函数表达式*/
  12. // 解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);
  13. // 至于函数表达式,则必须等到解析器执行到它所在的代码行,才会被真正被解释执行。
  14. //
  15. alert(sum(10, 10));
  16. // 函数声明
  17. function sum(num1, num2){
  18. return num1 + num2;
  19. }
  20. // 函数表达式
  21. sum = function(num1, num2){ // 执行会报错
  22. return num1 + num2;
  23. }
  24. // ==========
  25. /*函数名本身就是变量,函数可以作为值来使用*/
  26. // 1.作为参数传递;2.作为函数结果返回
  27. function callSomeFunction(someFunction, someArgument){
  28. return someFunction(someArgument);
  29. }
  30. // 要访问函数的指针而不执行函数的话,必须去掉函数名后面的那对圆括号
  31. // ==========
  32. /*函数内部属性 arguments 和 this*/
  33. // arguments 还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数
  34. // 阶乘函数(一般用到递归算法)
  35. function factorial(num) {
  36. if(num <= 1){
  37. return 1;
  38. }else{
  39. return num * factorial(num - 1); //问题:函数执行与函数名factorial紧紧耦合了
  40. }
  41. }
  42. // 使用 callee 属性 解决 耦合
  43. function factorial(num){
  44. if(num <= 1){
  45. return 1;
  46. }else{
  47. // 严格模式下访问 callee 会导致错误
  48. return num * arguments.callee(num -1);// 解除了函数体内的代码与函数名的耦合状态了
  49. }
  50. }
  51. //
  52. var trueFactorial = factorial; //实际上是在另一个位置上保存了一个函数的指针。
  53. factorial = function(){
  54. return 0;
  55. }
  56. alert(trueFactorial(5)); //120
  57. alert(factorial(5)); // 0
  58. //=== this
  59. // 在调用函数前,this的值并不确定,因此 this 可能会在代码执行过程中引用不同的对象。
  60. window.color = 'red';
  61. var o = {
  62. color: 'blue'
  63. }
  64. function sayColor(){
  65. alert(this.color);
  66. }
  67. // 函数的名字仅仅是一个包含指针的变量而已.
  68. o.sayColor = sayColor;
  69. o.sayColor();
  70. // 即使在不同的环境中执行,全局的 sayColor() 函数与 o.sayColor() 指向的仍然是同一个函数
  71. // 只是执行作用域不同
  72. // ==========
  73. /*函数属性和方法*/
  74. // 每个函数都包含两个非继承而来的方法:apply() 和 call()
  75. // 用途:在特定的作用域中调用函数,实际等于设置函数体内this对象的值。
  76. // apply(运行函数的作用域, 参数数组)
  77. // call(运行函数的作用域, 参数列表)
  78. window.color = 'red';
  79. var o = {
  80. color: 'blue'
  81. };
  82. function sayColor(){
  83. alert(this.color);
  84. }
  85. sayColor();
  86. sayColor.call(this);
  87. sayColor.call(window);
  88. sayColor.call(o);
  89. // 使用call 或 apply 来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系
  90. // ==== bind() 创建一个函数的实例,其 this的值会被绑定到传给 bind() 函数的值
  91. window.color = 'red';
  92. var o = {
  93. color: 'blue'
  94. }
  95. function sayColor(){
  96. alert(this.color);
  97. }
  98. var objectSayColor = sayColor.bind(o);
  99. objectSayColor(); // blue
复制代码
面向对象
  1. /*任何函数,只要通过 new 操作符来调用,那它就可以做为 构造函数*/
  2. function Person(name, age, job){
  3. this.name = name;
  4. this.age = age;
  5. this.job = job;
  6. this.sayName = function(){
  7. alert(this.name);
  8. };
  9. }
  10. // 当作构造函数使用
  11. var person = new Person('lisi', 29, 'software engineer');
  12. person.sayName(); // lisi
  13. // 作为普通函数调用
  14. Person('wangwu', 22, 'doctor'); // 添加的window
  15. sayName(); // wangwu
  16. // 在另一个对象的作用域中调用
  17. var o = new Object();
  18. Person.call(o, 'zhangsan', 33, 'nurse');
  19. o.sayName(); // zhangsan
  20. // =============
  21. /*
  22. * 每个函数都有一个 prototype 属性,这个属性指向函数的原型对象。
  23. * 默认情况下,所有原型对象都会自动获得一个 constructor 属性
  24. */
  25. function Person(){
  26. }
  27. Person.prototype.name = 'lisi';
  28. Person.prototype.age = 33;
  29. Person.prototype.job = 'software engineer';
  30. Person.prototype.sayName = function(){
  31. console.log(this.name);
  32. };
  33. // 简单的原型语法
  34. // 将 Person.prototype 设置为一个 以 对象字面量形式创建的新对象
  35. // 结果相同,但是 constructor属性 已经不指向 Person 了
  36. // 本质上 重写了默认的 prototype 对象,因此 constructor 属性也就变成了新对象的 constructor属性(指向 Object构造函数)
  37. // 尽管 instanceof 操作符还能返回正确的结果,但通过constructor已经无法确定对象的类型了
  38. Person.prototype = {
  39. constructor: Person, // 将 constructor 设置回适当的值
  40. name: 'lisi',
  41. age: 33,
  42. job: 'software engineer',
  43. sayName: function(){
  44. console.log(this.name);
  45. }
  46. }
  47. var person1 = new Person();
  48. var person2 = new Person();
  49. person1.name = 'wangwu';
  50. console.log(person1.name);
  51. console.log(person2.name);
  52. // hasOwnProperty() 检测一个属性是存在与 实例中,还是存在于 原型中
  53. // true:只在给定属性中存在于对象实例中
  54. // for in 由于 in 操作符只要通过对象能够访问到属性就返回 true
  55. // 而 hasOwnProperty() 只在属性存在于对象实例中才 返回 true
  56. // =========
  57. /*
  58. * 原型的动态型
  59. */
  60. function Person() {
  61. }
  62. var friend = new Person();
  63. // 重写原型对象后,把原型修改为另外一个对象就等于切断了 构造函数与最初原型之间的联系。
  64. Person.prototype = {
  65. constructor: Person, // 将 constructor 设置回适当的值
  66. name: 'lisi',
  67. age: 33,
  68. job: 'software engineer',
  69. sayName: function(){
  70. console.log(this.name);
  71. }
  72. }
  73. friend.sayName(); // error
  74. // 实例中的指针 仅指向原型,而不指向构造函数
  75. //=====
  76. /*
  77. * 创建自定义类型 组合使用 构造函数模式 + 原型模式
  78. */
  79. // 构造函数模式( 用于定义属于每个实例的属性值,同属性名但不同值)
  80. function Person(name, age, job) {
  81. this.name = name;
  82. this.age = age;
  83. this.job = job;
  84. this.friends = ['shelby', 'court'];
  85. }
  86. // 原型模式(用于定义 方法和属性 的 共享!!!)
  87. Person.prototype = {
  88. constructor: Person, // 将 constructor 设置回适当的值
  89. sayName: function(){
  90. console.log(this.name);
  91. }
  92. };
  93. var person1 = new Person('nicholas', 29, 'software engineer');
  94. var person2 = new Person('greg', 22, 'doctor');
  95. person1.friends.push('van');
  96. console.log(person1.friends);
  97. console.log(person2.friends);
  98. console.log(person1.friends === person2.friends);
  99. console.log(person1.sayName === person1.sayName);
  100. // 每个实例属性都是在构造函数中定义的,而由所有实例共享的属性 constructor 和 方法则是在原型中定义的
复制代码
继承
  1. /*
  2. * 每个函数都有一个 prototype(原型) 属性,这个属性是一个指针,指向一个对象,
  3. * 而这个对象的用途是包含可以由(特定类型的所有实例共享的属性和方法)
  4. */
  5. /*
  6. * 构造函数、原型、实例的关系
  7. * 1.每个构造函数都有一个 原型对象
  8. * 2.原型对象都包含一个指向构造函数的指针
  9. * 3.实例都包含一个指向原型对象的内部指针
  10. */
  11. function SuperType(){
  12. this.property = true;
  13. }
  14. SuperType.prototype.getSuperValue = function(){
  15. return this.property;
  16. }
  17. function SubType(){
  18. this.subProperty = false;
  19. }
  20. // 继承了 SuperType
  21. SubType.prototype = new SuperType();
  22. SubType.prototype.getSubValue = function(){
  23. return this.subProperty;
  24. }
  25. var instance = new SubType();
  26. console.log(instance.getSubValue());
  27. console.log(instance.getSuperValue());
复制代码


回复

使用道具 举报