继续创造,加速成长!这是我参与「日新方案 10 月更文挑战」的第24天,点击检查活动详情

JavaScript 要点常识

了解结构函数原型目标的语法特征,把握 JavaScript 中面向目标编程的完成办法,根据面向目标编程思维完成 DOM 操作的封装。

  • 了解面向目标编程的一般特征
  • 把握根据结构函数原型目标的逻辑封装
  • 把握根据原型目标完成的承继
  • 了解什么原型链及其作用
  • 能够处理程序反常提升程序执行的健壮性

一、面向目标

学习 JavaScript 中根据原型的面向目标编程序的语法完成,了解面向目标编程的特征。

面向目标编程是一种程序设计思维,它具有 3 个显著的特征:封装、承继、多态。

1.1 封装

封装的实质是将具有相关的代码组合在一同,其优势是能够确保代码复用且易于保护,函数是最典型也是最基础的代码封装方式,面向目标思维中的封装仍以函数为基础,但供给了更高级的封装方式。

命名空间

先来回顾一下以往代码封装的方式:

<script>
 // 普通目标(命名空间)方式的封装
 let beats = {
  name: '狼',
  setName: function (name) {
   this.name = this.name;
   },
  getName() {
   console.log(this.name);
   }
  }
​
 beats.setName('熊');
 beats.getName();
</script>

以往以普通目标(命名空间)方式封装的代码仅仅单纯把一系列的变量或函数组合到一同,一切的数据变量都被用来同享(运用 this 拜访)。

结构函数

对比以下经过面向目标的结构函数完成的封装:

<script>
 function Person() {
  this.name = '佚名';
  // 设置姓名
  this.setName = function (name) {
   this.name = name;
   }
  // 读取姓名
  this.getName = () => {
   console.log(this.name);
   }
  }
​
 // 实例对像,获得了结构函数中封装的一切逻辑
 let p1 = new Person();
 p1.setName('小明');
 console.log(p1.name);
​
 // 实例目标
 let p2 = new Person();
 console.log(p2.name);
</script>

同样的将变量和函数组合到了一同并能经过 this 完成数据的同享,所不同的是凭借结构函数创立出来的实例目标之间是彼此不影响的。

总结:

  1. 结构函数体现了面向目标的封装特性
  2. 结构函数实例创立的目标彼此独立、互不影响
  3. 命名空间式的封装无法确保数据的独立性

注:能够举一些比如,如女娲造人等比如,加深对结构函数的了解。

原型目标

实际上每一个结构函数都有一个名为 prototype 的特点,译成中文是原型的意思,prototype 的是目标类据类型,称为结构函数的原型目标,每个原型目标都具有 constructor 特点代表了该原型目标对应的结构函数。

<script>
 function Person() {
  
  }
​
 // 每个函数都有 prototype 特点
 console.log(Person.prototype);
</script>

了解了 JavaScript 中结构函数与原型目标的联系后,再来看原型目标具体的作用,如下代码所示:

<script>
 function Person() {
  // 此处未界说任何办法
  }
​
 // 为结构函数的原型目标增加办法
 Person.prototype.sayHi = function () {
  console.log('Hi~');
  }
 // 实例化
 let p1 = new Person();
 p1.sayHi(); // 输出成果为 Hi~
</script>

结构函数 Person 中未界说任何办法,这时实例目标调用了原型目标中的办法 sayHi,接下来改动一下代码:

<script>
 function Person() {
  // 此处界说同名办法 sayHi
  this.sayHi = function () {
   console.log('嗨!');
   }
  }
​
 // 为结构函数的原型目标增加办法
 Person.prototype.sayHi = function () {
  console.log('Hi~');
  }
​
 let p1 = new Person();
 p1.sayHi(); // 输出成果为 嗨!
</script>

结构函数 Person 中界说与原型目标中相同称号的办法,这时实例目标调用则是结构函中的办法 sayHi

经过以上两个简单示例不难发现 JavaScript 中目标的工作机制:当拜访目标的特点或办法时,先在当时实例目标是查找,然后再去原型目标查找,而且原型目标被一切实例同享。

<script>
    function Person() {
  // 此处界说同名办法 sayHi
  this.sayHi = function () {
   console.log('嗨!' + this.name);
   }
  }
​
 // 为结构函数的原型目标增加办法
 Person.prototype.sayHi = function () {
  console.log('Hi~' + this.name);
  }
 // 在结构函数的原型目标上增加特点
 Person.prototype.name = '小明';
​
 let p1 = new Person();
 p1.sayHi(); // 输出成果为 嗨!
 
 let p2 = new Person();
 p2.sayHi();
</script>

总结:结合结构函数原型的特征,实际开发重往往会将封装的功用函数增加到原型目标中。

1.2 承继

承继是面向目标编程的另一个特征,经过承继进一步提升代码封装的程度,JavaScript 中大多是凭借原型目标完成承继的特性。

龙生龙、凤生凤、老鼠的儿子会打洞描述的正是承继的意义,分别封装中国人和日本人的行为特征来了解编程中承继的意义,代码如下:

<script>
 // 封装中国人的行为特征
 function Chinese() {
  // 中国人的特征
  this.arms = 2;
  this.legs = 2;
  this.eyes = 2;this.skin = 'yellow';
  this.language = '中文';
​
  // 中国人的行为
  this.walk = function () {}
  this.sing = function () {}
  this.sleep = function () {}
  }
​
 // 封装日本人的行为特征
 function Japanese() {
  // 日本人的特征
  this.arms = 2;
  this.legs = 2;
  this.eyes = 2;this.skin = 'yellow';
  this.language = '日文';
​
  // 日本人的行为
  this.walk = function () {}
  this.sing = function () {}
  this.sleep = function () {}
  }
</script>

其实咱们都知道不管是中国人、日本人仍是其它民族,人们的大部分特征是一致的,但是体现在代码中时人的相同的行为特征被重复编写了屡次,代码显得十分冗余,咱们能够将重复的代码抽离出来:

原型承继

根据结构函数原型目标完成面向目标的承继特性。

<script>
 // 一切人
 function Person() {
  // 人的特征
  this.arms = 2;
  this.legs = 2;
  this.eyes = 2;
  
  // 人的行为
  this.walk = function () {}
  this.sing = function () {}
  this.sleep = function () {}
  }
 
 // 中国人
 function Chinese() {
  this.skin = 'yellow';
  this.language = '中文';
  }
 // 日本人
    function Japanese() {
  this.skin = 'yellow';
  this.language = '日文';
  }
</script>

上述代码能够了解成将 ChineseJapanese 共有的特点和办法提取出来了,也就是说 ChineseJapanese 需要【同享】一些特点和办法,而原型目标的特点和办法恰好是能够被用来同享的,因此咱们看如下代码:

<script>
 // 中国人
 function Chinese() {
  this.skin = 'yellow';
  this.language = '中文';
  }
 // 日本人
    function Japanese() {
  this.skin = 'yellow';
  this.language = '日文';
  }
 
 // 人们【共有】的行为特征
 let people = {
  // 人的特征
  arms: 2,
  legs: 2,
  eyes:2,
  // 人的行为
  walk: function () {},
  sleep: function () {},
  sing: function () {}
  }
 
 // 为 prototype 重新赋值
 Chinese.prototype = people;
 Chinese.prototype.constructor = Chinese;
</script>

如下图所示:

创立目标 people 将公共的的特点和办法独立出来,然后赋值给结构函数的 prototype 这样不管有多少个民族都能够同享公共的特点和办法了:

<script>
 // 人们【共有】的行为特征
 let people = {
  // 人的特征
  arms: 2,
  legs: 2,
  eyes:2,
  // 人的行为
  walk: function () {},
  sleep: function () {},
  sing: function () {}
  }
 
 // 中国人
 function Chinese() {
  this.skin = 'yellow';
  this.language = '中文';
  }
 // 日本人
    function Japanese() {
  this.skin = 'yellow';
  this.language = '日文';
  }
 
 function Englist() {
  this.skin = 'white';
  this.language= '英文';
  }
 
 // 中国人
 Chinese.prototype = people;
 Chinese.prototype.constructor = Chinese;
 
 let c1 = new Chinese();
 // 日本人
 Japanese.prototype = people;
 Janpanese.prototype.constructor = Japanese;
 // 英国人
 English.prototype = people;
 English.prototype.constructor = English;
 
 // ...
</script>

承继是一种能够“不劳而获”的手法!!!上述代码中 ChineseJapaneseEnglish 都轻松的获得了 people 的公共的办法和特点,咱们说 ChineseJapaneseEnglish 承继了 people

上述代码中是以命名空间的方式完成的承继,事实上 JavaScript 中承继更常见的是凭借结构函数来完成:

<script>
 // 一切人
 function Person() {
  // 人的特征
  this.arms = 2;
  this.legs = 2;
  this.eyes = 2;
​
  // 人的行为
  this.walk = function () {}
  this.sing = function () {}
  this.sleep = function () {}
  }
​
 // 封装中国人的行为特征
 function Chinese() {
  // 中国人的特征
  this.skin = 'yellow';
  this.language = '中文';
  }
​
 // 封装日本人的行为特征
 function Japanese() {
  // 日本人的特征
  this.skin = 'yellow';
  this.language = '日文';
  }
​
 // human 是结构函数 Person 的实例
 let human = new Person();
​
 // 中国人
 Chinese.prototype = human;
 Chinese.prototype.constructor = Chinese;
 // 日本人
 Japanese.prototype = human;
 Japanese.prototype.constructor = Japanese;
</script>

如下图所示:

原型链

根据原型目标的承继使得不同结构函数的原型目标相关在一同,而且这种相关的联系是一种链状的结构,咱们将原型目标的链状结构联系称为原型链,

<script>
  // Person 结构函数
  function Person() {
    this.arms = 2;
    this.walk = function () {}
  }
  // Person 原型目标
  Person.prototype.legs = 2;
  Person.prototype.eyes = 2;
  Person.prototype.sing = function () {}
  Person.prototype.sleep = function () {}
  // Chinese 结构函数
  function Chinese() {
    this.skin = 'yellow';
    this.language = '中文';
  }
  // Chinese 原型目标
  Chinese.prototype = new Person();
  Chinese.prototype.constructor = Chinese;
  // 实例化
  let c1 = new Chinese();
  console.log(c1);
</script>

在 JavaScript 目标中包含了一个非标预备的特点 __proto__ 它指向了结构函数的原型目标,经过它能够清楚的检查原型目标的链状结构。

JavaScript基础笔记收拾(六)