IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> J S 高级知识汇总——构造函数 -> 正文阅读

[JavaScript知识库]J S 高级知识汇总——构造函数

一、构造函数

1.1 概述

1.2 对象的三种创建方式(复习)

  1. 字面量方式

    var obj = {};

  2. new关键字

    var obj = new Object();

  3. 构造函数方式

    function Person(name,age){
     ?this.name = name;
     ?this.age = age;
    }
    var obj = new Person('zs',12);

1.3 构造函数

?

// 3. 利用构造函数创建对象
function Star(uname, age) {
 ? ?this.uname = uname;
 ? ?this.age = age;
 ? ?this.sing = function() {
 ? ? ? ?console.log('我会唱歌');
?
 ?  }
}
?
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友', 19);
console.log(ldh);
ldh.sing();
zxy.sing();

1.4 静态成员和实例成员

成员:属性和方法。

实例成员

实例成员就是构造函数内部通过this添加的成员,

如下列代码中:uname age sing 就是实例成员,

实例成员只能通过实例化的对象来访问

 // 构造函数中的属性和方法我们称为成员, 成员可以添加
function Star(uname, age) {
 ? ? this.uname = uname;
 ? ? this.age = age;
 ? ? this.sing = function() {
 ? ? console.log('我会唱歌');
 ?  }
}
var ldh = new Star('刘德华', 18);
console.log(ldh.uname);//实例成员只能通过实例化的对象来访问

静态成员

构造函数本身也是1个对象!

静态成员:在构造函数本身上添加的成员。

如下列代码中 sex 就是静态成员,静态成员

只能通过构造函数来访问

function Star(uname, age) {
 ? ? this.uname = uname;
 ? ? this.age = age;
 ? ? this.sing = function() {
 ? ? console.log('我会唱歌');
 ?  }
}
// 静态成员 在构造函数本身上添加的成员  sex 就是静态成员
Star.sex = '男';
var ldh = new Star('刘德华', 18);
console.log(Star.sex);//静态成员只能通过构造函数来访问

二、原型对象

2.1 构造函数的问题

构造函数创建对象很好用,但是如果把方法定义在构造函数内,就存在浪费内存的问题。

我们的公共属性定义到构造函数里面, 公共的方法我们放到原型对象身上。

2.2 构造函数的原型prototype

构造函数通过原型分配的函数是所有对象所共享的。

JavaScript 规定,每一个构造函数都有一个prototype 属性,指向另一个对象,这个对象叫做【原型对象】。

我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。

function Star(uname, age) {
 ? ?// 构造函数中定义属性
 ? ?this.uname = uname;
 ? ?this.age = age;
}
// 把方法定义到原型对象身上
Star.prototype.sing = function() {
 ? ?console.log('我会唱歌');
}
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友', 19);
?
ldh.sing();
zxy.sing();
?
// 所有的实例对象,共用一个方法,省内存
console.log(ldh.sing === zxy.sing);

2.3 对象原型

实例对象都有一个属性 __proto__ 指向构造函数的 prototype 原型对象。
?
之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 __proto__ 原型的存在。
?
__proto__对象原型和原型对象 prototype 是等价的。
?
__proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象 prototype。
?

?

2.4 constructor构造函数

?

如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数如:

function Star(uname, age) {
 ? ? this.uname = uname;
 ? ? this.age = age;
 }
 // 很多情况下,我们需要手动的利用constructor 这个属性指回 原来的构造函数
 Star.prototype = {
 // 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
 ? constructor: Star, // 手动设置指回原来的构造函数
 ? sing: function() {
 ? ? console.log('我会唱歌');
 ? },
 ? movie: function() {
 ? ? console.log('我会演电影');
 ? }
}
var zxy = new Star('张学友', 19);

2.5 三角关系

构造函数、实例对象和原型对象的三角关系。

1.构造函数的prototype属性指向了构造函数原型对象
2.实例对象是由构造函数创建的,实例对象的__proto__属性指向了构造函数的原型对象
3.构造函数的原型对象的constructor属性指向了构造函数,实例对象的原型的constructor属性也指向了构造函数

四、原型链与对象成员的查找规则

4.1 原型链

<!--任何原型对象也是一个对象,该对象就有 __proto__ 属性,这样一层一层往上找,就形成了一条链,我们称此为原型链;-->

4.2 对象成员的查找机制

当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
?
如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。
?
如果还没有就查找:原型对象的原型(Object的原型对象)。
?
依此类推一直找到 Object 为止(null)。

沿着原型链查找!!

五、原型对象的应用

5.1 原型对象函数中this指向

不管构造函数中的this,还是原型对象中的this,都指向我们new出来的实例对象。

<script>
 ? ?function Star(uname, age) {
 ? ? ? ?this.uname = uname;
 ? ? ? ?this.age = age;
 ?  }
 ? ?var that;
 ? ?Star.prototype.sing = function() {
 ? ? ? ?console.log('我会唱歌');
 ? ? ? ?that = this;
 ?  }
 ? ?var ldh = new Star('刘德华', 18);
 ? ?// 1. 在构造函数中,里面this指向的是对象实例 ldh
 ? ?ldh.sing();
 ? ?console.log(that === ldh);
?
 ? ?// 2.原型对象函数里面的this 指向的是 实例对象 ldh
</script>

5.2 通过原型为数组扩展内置方法

可以通过原型对象,对原来的内置对象进行扩展自定义的方法。比如给数组增加自定义求偶数和的功能。

// 系统中内置了很多构造函数:例如:Object、Array
// Array构造函数也有一个对应的原型对象
Array.prototype.sum = function() {
 ? ?var sum = 0;
 ? ?for (var i = 0; i < this.length; i++) {
 ? ? ? ?sum += this[i];
 ?  }
 ? ?return sum;
};
// 数组的实例对象 arr
var arr = [1, 2, 3];
// 调用sum方法(成员的查找规则)
console.log(arr.sum());
console.log(Array.prototype);
?
// 数组的实例对象 arr1
var arr1 = new Array(11, 22, 33);
console.log(arr1.sum());

六、继承

子构造函数 继承 父构造函数!

6.1 call()方法

调用这个函数, 并且修改函数运行时的 this 指向 。

  • call()可以调用函数

  • call()可以修改this的指向,使用call()的时候 参数1是修改后的this指向,参数2,参数3。。。是函数的实参列表。

function fn(x, y) {
 ? ? console.log('我想喝手磨咖啡');
 ? ? console.log(this);
 ? ? console.log(x + y);
}
 ?var o = {
    name: 'andy'
  };
 ?// fn();
 ?// 1. call() 可以调用函数
 ?// fn.call();
 ?// 2. call() 可以改变这个函数的this指向 此时这个函数的this 就指向了o这个对象
 ?fn.call(o, 1, 2);

6.2 继承属性

  1. 先定义一个父构造函数

  2. 再定义一个子构造函数

  3. 子构造函数继承父构造函数的属性(使用call方法)

// 1. 父构造函数
 function Father(uname, age) {
 ? // this 指向父构造函数的对象实例
 ? this.uname = uname;
 ? this.age = age;
 }
 ?// 2 .子构造函数 
function Son(uname, age, score) {
 ?// this 指向子构造函数的对象实例 ldh
 ?// 3.使用call方式实现子继承父的属性【调用父构造函数,并让其this变为ldh】
 ?Father.call(this, uname, age);
 ?this.score = score;
}
var ldh = new Son('刘德华', 18, 100);
console.log(son);

6.3 继承方法

借用原型对象继承方法!

  1. 先定义一个父构造函数

  2. 再定义一个子构造函数

  3. 修改子构造函数的原型对象(new 父构造函数得到的对象)

// 1. 父构造函数
function Father(uname, age) {
 ?// this 指向父构造函数的对象实例
 ?this.uname = uname;
 ?this.age = age;
}
Father.prototype.money = function() {
 ?console.log(100000);
 };
 // 2 .子构造函数 
 ?function Son(uname, age, score) {
 ? ? ?// this 指向子构造函数的对象实例
 ? ? ?Father.call(this, uname, age);
 ? ? ?this.score = score;
  }
// Son.prototype = Father.prototype;  这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
 ?Son.prototype = new Father();
 ?// 如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数
 ?Son.prototype.constructor = Son;
 ?// 这个是子构造函数专门的方法
 ?Son.prototype.exam = function() {
 ? ?console.log('孩子要考试');
  }
 ?var son = new Son('刘德华', 18, 100);
 ?console.log(son);

七、类的本质

?

?

<script>
 ? ?// ES6 之前通过 构造函数 + 原型 实现面向对象编程
 ? ?// (1)构造函数有原型对象prototype
 ? ?// (2)构造函数原型对象prototype里面有constructor 指向构造函数本身
 ? ?// (3)构造函数可以通过原型对象添加方法
 ? ?// (4)构造函数创建的实例对象有__proto__原型指向 构造函数的原型对象
?
 ? ?// ES6 通过 类 实现面向对象编程
 ? ?class Star {
?
 ?  }
 ? ?console.log(typeof Star);
 ? ?// 1. 类的本质其实还是一个函数,我们也可以简单的认为 类就是 构造函数的另外一种写法
 ? ?// (1)类有原型对象prototype
 ? ?console.log(Star.prototype);
 ? ?// (2)类 也有原型对象,这个原型对象指向类本身
 ? ?console.log(Star.prototype.constructor);
 ? ?// (3)类 可以通过原型对象添加方法
 ? ?Star.prototype.sing = function() {
 ? ? ? ?console.log('冰雨');
 ?  };
 ? ?// (4)类创建的实例对象,有__proto__原型,指向类的原型对象
 ? ?var ldh = new Star();
 ? ?console.dir(ldh);
 ? ?console.log(ldh.__proto__ === Star.prototype);
</script>

八、ES5新增方法

8.1 数组方法forEach遍历数组

 arr.forEach(function(value, index, array) {
 ? ? ? //参数一是:数组元素
 ? ? ? //参数二是:数组元素的索引
 ? ? ? //参数三是:当前的数组
 })
 ?//相当于数组遍历的 for循环 没有返回值

8.2 数组方法filter过滤数组

 ?var arr = [12, 66, 4, 88, 3, 7];
 ?var newArr = arr.filter(function(value, index,array) {
     //参数一是:数组元素
 ? ? //参数二是:数组元素的索引
 ? ? //参数三是:当前的数组
 ? ? return value >= 20;
  });
 ?console.log(newArr);//[66,88] //返回值是一个新数组

8.3 数组方法some

some 查找数组中是否有满足条件的元素 
 var arr = [10, 30, 4];
 var flag = arr.some(function(value,index,array) {
 ? ?//参数一是:数组元素
 ? ? //参数二是:数组元素的索引
 ? ? //参数三是:当前的数组
 ? ? return value < 3;
  });
console.log(flag);//返回值是布尔值,只要查找到满足条件的一个元素就立马终止循环

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-14 15:50:58  更:2021-12-14 15:53:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:45:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码