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

yizhihongxing

以下是详细讲解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 获取滚动条位置等信息的函数可以帮助我们在开发网页时,实现各种复杂的滚动效果。下面,我将为大家详细讲解相关函数的使用方法和示例演示。 获取滚动条位置的函数:scrollY scrollY 函数是用于获取文档的垂直滚动距离的函数。其用法如下: var scrollPos = window.scrollY; 其中,window 是指当前窗口,…

    JavaScript 2023年6月11日
    00
  • Vuex的各个模块封装的实现

    Vuex是Vue.js的官方状态管理库。它通过对状态的集中式管理来解决组件之间共享状态管理的问题,让我们可以更好地组织代码和管理状态。Vuex中的各个模块都有特定的功能和职责,本文介绍了各个模块的封装的实现方式。 状态(State) 在Vuex中,状态是存储在store中的数据,我们一般将所有的状态都放在一个对象里。要访问状态信息,需要使用getter(可理…

    JavaScript 2023年6月11日
    00
  • js表单事件详细汇总

    关于“js表单事件详细汇总”的完整攻略,我将分为五部分进行讲解。 第一部分:什么是表单事件 表单事件是在用户与表单交互时触发的JavaScript方法。表单事件绑定在表单元素上,例如input、button、form等。 第二部分:表单事件的使用方法 表单事件可以通过addEventListener()或on事件属性来绑定。addEventListener(…

    JavaScript 2023年6月10日
    00
  • 一起来学习一下JavaScript的事件流

    关于JavaScript事件流,我为大家准备了一份完整攻略,一起来学习一下。 什么是JavaScript事件流 JavaScript事件流是指浏览器中发生事件(如鼠标点击、键盘输入等)时,事件在DOM树结构中按照特定顺序发送和处理的过程。这个过程包含三个阶段:捕获阶段、目标阶段和冒泡阶段。 捕获阶段 在事件到达目标元素之前,从根节点到目标元素之间的所有节点都…

    JavaScript 2023年6月10日
    00
  • js实现String.Fomat的实例代码

    实现一个类似于String.Format的函数,需要掌握 JavaScript 中字符串的相关知识和操作方法,主要包括字符串的拼接和格式化,正则表达式等。 下面是实现String.Format的详细攻略: 1. 在原型链上添加Format方法 JavaScript 中所有对象都有一个__proto__属性,指向该对象的原型。为了实现类似于C#中的String…

    JavaScript 2023年5月28日
    00
  • JS判断数组是否包含某元素实现方法汇总

    首先,判断数组是否包含某一元素是JavaScript中非常基本的操作之一。在这里我们将介绍几种实现方法并提供示例说明。 1. 方法一:使用indexOf函数 使用indexOf函数是判断数组是否包含某元素的简便方法之一。该函数会返回元素在数组中的下标,如果元素不在数组中则返回-1。因此只需判断indexOf函数的返回值是否为-1即可得知元素是否在数组中。 下…

    JavaScript 2023年5月27日
    00
  • javascript实现图片轮播简单效果

    下面是“javascript实现图片轮播简单效果”的完整攻略: 1. 准备工作 在开始实现图片轮播前,需要先准备好相关的HTML代码、CSS样式和JavaScript脚本。具体的操作如下: 1.1 HTML代码 首先,在HTML文件中添加一个包含图片的容器,例如: <div class="slideshow"> <img…

    JavaScript 2023年6月11日
    00
  • VBS一键配置VOIP脚本代码

    1. 确定脚本的功能 在编写脚本代码之前,首先需要确定脚本的功能。在这个例子中,脚本的功能是“一键配置VOIP”,也就是帮助用户配置环境以便进行语音通话。具体的配置包括网络设置,软件安装等等。 2. 创建VBS脚本文件 创建一个新的文本文件,然后将文件后缀名改为“.vbs”来创建一个VBS脚本文件。接着,在该文件中编写代码。 3. 编写脚本代码 在脚本代码中…

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