JavaScript高级程序设计(第三版)学习笔记6、7章

以下是详细讲解JavaScript高级程序设计(第三版)学习笔记6、7章的完整攻略。

6章 对象

6.1 创建对象

6.1.1 工厂模式创建对象

工厂模式是一种常用的对象创建方法,使用函数创建对象可以解决创建多个类似对象的问题,但无法解决对象识别的问题(即无法通过某种方式判断一个对象的类型)。使用工厂模式创建的对象无法识别其类型,只能通过检查其属性来判断对象类型。

以下是使用工厂模式创建对象的示例代码:

function createPerson(name, age) {
  let person = new Object();
  person.name = name;
  person.age = age;
  person.sayName = function() {
    console.log(this.name);
  };
  return person;
}

let person1 = createPerson('Tom', 18);
let person2 = createPerson('Jerry', 20);

person1.sayName(); // 输出 "Tom"
person2.sayName(); // 输出 "Jerry"

6.1.2 构造函数创建对象

构造函数在执行时,会创建一个新的对象,将this关键字绑定到对象上,并自动在对象上创建出必要的属性和方法。使用构造函数创建的对象可以通过instanceof操作符来判断对象类型,但是每个方法都需要重新定义,会占用过多内存。

以下是使用构造函数创建对象的示例代码:

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.sayName = function() {
    console.log(this.name);
  };
}

let person1 = new Person('Tom', 18);
let person2 = new Person('Jerry', 20);

person1.sayName(); // 输出 "Tom"
person2.sayName(); // 输出 "Jerry"
console.log(person1 instanceof Person); // 输出 true
console.log(person2 instanceof Person); // 输出 true

6.1.3 原型模式创建对象

使用原型模式创建对象可以共享方法和属性,可以大大减少内存占用。原型模式创建的对象其类型是一致的,但所有实例共享同一个属性或方法,如果某个实例修改了共享的属性,将会影响到所有实例。

以下是使用原型模式创建对象的示例代码:

function Person() {
}

Person.prototype.name = "Tom";
Person.prototype.age = 18;
Person.prototype.sayName = function() {
  console.log(this.name);
};

let person1 = new Person();
let person2 = new Person();

person1.sayName(); // 输出 "Tom"
person2.sayName(); // 输出 "Tom"
console.log(person1 instanceof Person); // 输出 true
console.log(person2 instanceof Person); // 输出 true

6.1.4 组合使用构造函数和原型模式创建对象

组合使用构造函数和原型模式创建对象可以解决私有属性和共有属性的问题,既可以共享方法和属性,也可以使每个对象都有自己的属性。

以下是组合使用构造函数和原型模式创建对象的示例代码:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayName = function() {
  console.log(this.name);
};

let person1 = new Person('Tom', 18);
let person2 = new Person('Jerry', 20);

person1.sayName(); // 输出 "Tom"
person2.sayName(); // 输出 "Jerry"
console.log(person1 instanceof Person); // 输出 true
console.log(person2 instanceof Person); // 输出 true

6.2 对象的继承

6.2.1 原型链继承

原型链继承是通过将一个对象的原型指向另一个对象,使得前者可以访问到后者的属性和方法,从而实现继承。但是使用原型链继承可能会导致属性共享和无法传递参数的问题。

以下是使用原型链继承的示例代码:

function SuperType() {
  this.property = true;
}

SuperType.prototype.getSuperValue = function() {
  return this.property;
};

function SubType() {
  this.subproperty = false;
}

SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function() {
  return this.subproperty;
};

let instance = new SubType();
console.log(instance.getSuperValue()); // 输出 true
console.log(instance.getSubValue()); // 输出 false
console.log(instance instanceof SuperType); // 输出 true
console.log(instance instanceof SubType); // 输出 true

6.2.2 借用构造函数继承

借用构造函数继承是通过在子类构造函数内部调用父类构造函数,从而继承父类的属性和方法。但是使用这种方法只能继承父类的实例属性和方法,无法继承父类原型中定义的属性和方法。

以下是使用借用构造函数继承的示例代码:

function SuperType(name) {
  this.name = name;
}

function SubType() {
  SuperType.call(this, "Tom");

  this.age = 18;
}

let instance = new SubType();
console.log(instance.name); // 输出 "Tom"
console.log(instance.age); // 输出 18

6.2.3 组合继承

组合继承是通过同时使用原型链继承和借用构造函数继承来实现继承,既可以继承父类原型中的属性和方法,又可以继承父类的实例属性和方法。

以下是使用组合继承的示例代码:

function SuperType(name) {
  this.name = name;
}

SuperType.prototype.sayName = function() {
  console.log(this.name);
}

function SubType(name, age) {
  SuperType.call(this, name);

  this.age = age;
}

SubType.prototype = new SuperType();

let instance = new SubType("Tom", 18);
console.log(instance.name); // 输出 "Tom"
console.log(instance.age); // 输出 18
instance.sayName(); // 输出 "Tom"
console.log(instance instanceof SuperType); // 输出 true
console.log(instance instanceof SubType); // 输出 true

6.3 对象的拷贝

对象的拷贝可以使用深拷贝和浅拷贝两种方式来实现。浅拷贝只会拷贝对象的属性值,而不会拷贝对象的属性所指向的实际对象。深拷贝会拷贝对象的属性以及该属性所指向的对象。

以下是使用浅拷贝和深拷贝的示例代码:

// 浅拷贝示例
let obj = {name: "Tom", age: 18};
let obj2 = obj;
obj.name = "Jerry";
console.log(obj2.name); // 输出 "Jerry"

// 深拷贝示例
function deepCopy(obj) {
  let result = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      if (typeof obj[key] === "object") {
        result[key] = deepCopy(obj[key]);
      } else {
        result[key] = obj[key];
      }
    }
  }
  return result;
}

let obj = {name: {first: "Tom", last: "Jerry"}, age: 18};
let obj2 = deepCopy(obj);
obj.name.first = "Jerry";
console.log(obj2.name.first); // 输出 "Tom"

7章 函数表达式

7.1 递归

递归指的是函数调用自身的过程,可以使用递归来实现一些逻辑上复杂的功能,但是过多的递归可能会导致栈内存溢出的问题。

以下是使用递归实现阶乘的示例代码:

function factorial(num) {
  if (num <= 1) {
    return 1;
  } else {
    return num * factorial(num - 1);
  }
}

console.log(factorial(5)); // 输出 120

7.2 闭包

闭包是指一个函数可以访问和操作外部函数的变量和参数,从而可以访问函数执行时的作用域链中的变量。使用闭包可以实现数据私有化,即保护变量不受其他代码的干扰和污染。

以下是使用闭包实现数据私有化的示例代码:

function createCounter() {
  let count = 0;

  return {
    increment: function() {
      count++;
    },
    getCount: function() {
      return count;
    }
  };
}

let counter = createCounter();
counter.increment();
console.log(counter.getCount()); // 输出 1

7.3 立即调用函数表达式(IIFE)

立即调用函数表达式(IIFE)是指一个函数在定义时立即执行,可以用来创建局部作用域、保护命名空间和防止变量污染等。

以下是使用立即调用函数表达式(IIFE)创建局部作用域的示例代码:

(function() {
  let message = "Hello, world!";
  console.log(message);
})();

console.log(message); // 抛出未定义错误

7.4 函数绑定

函数绑定是指通过函数的bind()方法来改变函数内部this的指向,使其指向其他对象,从而实现函数调用时this指向的指定。

以下是使用函数绑定修改函数内部this指向的示例代码:

let obj1 = {
  name: "Tom"
};

let obj2 = {
  name: "Jerry"
};

function sayName() {
  console.log(this.name);
}

let sayName1 = sayName.bind(obj1);
let sayName2 = sayName.bind(obj2);

sayName1(); // 输出 "Tom"
sayName2(); // 输出 "Jerry"

至此,JavaScript高级程序设计(第三版)学习笔记6、7章的完整攻略已经介绍完毕。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript高级程序设计(第三版)学习笔记6、7章 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • Javascript 更新 JavaScript 数组的 uniq 方法

    下面是更新 JavaScript 数组的 uniq 方法的完整攻略: 1. 现状 目前,虽然 JavaScript 数组已有现成的 filter 函数可以用来过滤数组中重复的元素,但很多开发者经常需要自定义数组的 uniq 方法,以实现更加灵活的去重操作。目前,常见的去重实现方式有两种:基于 Set 对象的去重和基于对象属性的去重,其中基于 Set 的去重是…

    JavaScript 2023年5月27日
    00
  • 利用JS十分钟判断数组中存在元素的多种方式

    利用JS十分钟判断数组中存在元素的多种方式 在JavaScript中,判断一个数组中是否存在某个元素,是我们经常需要面对的问题。以下是几种实现此功能的方式。 方法一:使用includes()方法 ES6中,可以使用数组的includes()方法来判断是否包含某个元素。 示例代码: const arr = [1, 2, 3]; console.log(arr.…

    JavaScript 2023年5月27日
    00
  • JavaScript中Infinity(无穷数)的使用和注意事项

    让我详细为您讲解一下“JavaScript中Infinity(无穷数)的使用和注意事项”的完整攻略。 什么是Infinity Infinity是JavaScript中的一个特殊数值,表示正或负的无穷大,表示数值超出JavaScript可以表示的极限。具体地说,在JavaScript中,Infinity是一个大于任何数的数,可以表示一些过大的数字或计算出的无限…

    JavaScript 2023年5月28日
    00
  • javascript跑马灯抽奖实例讲解

    下面我将详细讲解“JavaScript跑马灯抽奖实例讲解”的完整攻略,包括示例说明: 1. 介绍 在网页中,常常需要用到一些动态效果来吸引用户,其中跑马灯和抽奖都是常见的实现方式。在本文中,我们将学习如何使用JavaScript实现跑马灯抽奖效果。 2. 实现原理 跑马灯抽奖是根据随机数来获取中奖结果的,而文字的滚动效果则是通过定时器来实现的。下面是实现跑马…

    JavaScript 2023年6月11日
    00
  • 基于js 各种排序方法和sort方法的区别(详解)

    针对“基于js 各种排序方法和sort方法的区别(详解)”这个话题,我将从以下几个方面进行详细讲解。 一、基础排序算法 在介绍各种排序算法之前,我们先了解一下几个基础排序算法:冒泡排序、插入排序和选择排序。 1. 冒泡排序 冒泡排序的基本思路是比较相邻的元素,如果前面的元素比后面的大,则交换这两个元素。每完成一轮比较,就可以确定一个最大的元素,并且这个最大的…

    JavaScript 2023年6月11日
    00
  • javascript制作幻灯片(360度全景图片)

    准备工作 在制作幻灯片之前,我们需要准备以下几个工作: HTML页面模板 360度全景图片 JavaScript库Three.js 其中,HTML页面模板是整个幻灯片的基础,而360度全景图片是幻灯片展示的内容,而JavaScript库Three.js是帮助我们实现幻灯片效果的工具。 引入Three.js库 首先需要在HTML页面中引入Three.js库,具…

    JavaScript 2023年6月11日
    00
  • JavaScript继承与多继承实例分析

    下面我将详细讲解“JavaScript继承与多继承实例分析”的完整攻略。 一、什么是JavaScript继承 继承是面向对象编程的重要概念之一。在JavaScript中,继承可以通过原型链来实现。原型链的基本思想是,每个JavaScript对象都有一个内部指针,指向它的原型对象。当我们试图访问一个对象的属性时,如果该对象自身不存在该属性,则会沿着原型链向上查…

    JavaScript 2023年6月10日
    00
  • Jquery Ajax学习实例 向页面发出请求,返回XML格式数据

    让我们来详细讲解一下JQuery Ajax学习实例,这里我会给出两个示例说明,为了方便描述,我会分成步骤来讲解。 基本概念 在开始之前,我们需要先理解一些基本概念。 AJAX AJAX 是一种与服务器交换数据并更新部分网页而不重载整个页面的技术。AJAX 不是新技术,它是使用了已有的技术,是一种将客户端脚本和服务器端脚本进行异步通信的技术。 JSON JSO…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部