程序员书籍笔记 程序员书籍笔记
  • HTML
  • CSS
  • JavaScript
  • 前端知识
  • Vue
  • MarkDown
  • git
  • Node.js
  • Linux
  • 51单片机
  • 四级
  • 第一学期课程
  • 操作系统
  • 计算机网络
  • 数据结构
  • 计算机组成原理
  • HTML5
  • Electron
  • 日记便签
  • 前端导航
GitHub (opens new window)
  • HTML
  • CSS
  • JavaScript
  • 前端知识
  • Vue
  • MarkDown
  • git
  • Node.js
  • Linux
  • 51单片机
  • 四级
  • 第一学期课程
  • 操作系统
  • 计算机网络
  • 数据结构
  • 计算机组成原理
  • HTML5
  • Electron
  • 日记便签
  • 前端导航
GitHub (opens new window)
  • HTML

  • CSS

  • JavaScript

    • es6

      • es6基础
      • es5的扩展
      • let和const命令
    • 基础
    • 运算符和数组
    • 函数
    • 对象和类型
    • 数据类型
    • js接口
    • DOM案例
    • 节点操作
    • BOM接口
    • 页面操作
    • 动画和轮播图
    • 本地存储
    • js面向对象
    • es6
    • ES6
    • js面向对象1
    • js面向对象2
      • 构造函数和原型
        • 创建对象的三种方式
        • 构造函数
        • 实例成员和静态成员
        • 构造函数原型 prototype
        • __proto__ 和prototype的关系
        • 原型 constructor 构造函数
        • 原型链
        • 扩展内置对象
        • call()方法
        • 原型对象继承原理
      • ES5新增方法
        • 数组方法
        • 综合使用
        • trim
        • Object.keys()
        • Object.defineProperty()
    • js面向对象3
  • GO

  • 正则表达式

  • java

  • TypeScript

  • react

  • 前端知识

  • jQuery

  • Python

  • C和C++

  • 前端和后端
  • JavaScript
yuadh
2022-02-03
目录

js面向对象2

# 构造函数和原型

# 创建对象的三种方式

  1. 利用 new Object() 创建对象

    var a = new Object();
    
    1
  2. 利用 对象字面量创建对象

    var a = {};
    
    1
  3. 利用构造函数

    function Star(){
        this.uname = uname;
        this.age = age;
        this.sing = function(){
            console.log('sing..');
        }
    }
    var yuadh = new Star('yuadh',20);
    
    1
    2
    3
    4
    5
    6
    7
    8

# 构造函数

构造函数 是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面

过程

  1. 在内存中创建一个新的空对象
  2. 让 this 指向这个新的对象
  3. 执行构造函数里面的代码,给这个新对象添加属性和方法
  4. 返回这个新对象(所以构造函数里面不需要return)

# 实例成员和静态成员

  1. 实例成员就是构造函数内部通过this添加的成员 , 示例成员只能通过实例化的对象来访问

  2. 静态成员 在构造函数本身上添加的成员

    Star.name = 'yuadh';
    console.log(Star.name);
    
    1
    2

# 构造函数原型 prototype

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

每一个构造函数都有一个 prototype 属性,指向另一个对象。注意这个 prototype 就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有

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

**原型对象:**一个对象,prototype 为原型对象。作用是 共享方法

Star.prototype.sing = function(){
    console.log('sing...');
}
1
2
3

# __proto__ 和prototype的关系

每个示例化对象都会有一个 __proto__ 属性指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 __proto__ 原型的存在

  • __proto__ 对象原型和原型对象 prototype 是等价的
  • __proto__ 对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但它是一个非标准属性

# 原型 constructor 构造函数

constructor 为构造函数 ,用来 __proto__和 prototype 指回构造函数本身

Star.prototype = {
    constructor: Star, // 修改prototype对象后 指会原来的构造函数
    sing: function(){
        console.log('singgg');
    },
    moive: function(){
    	console.log('moiveee');
	}
}
1
2
3
4
5
6
7
8
9

# 原型链

console.log(led.__proto__);

console.log(Star.prototype);

console.log(Star.prototype.__proto__);

console.log(Object.prototype);

console.log(Object.prototype.__proto__);

null;
1
2
3
4
5
6
7
8
9
10
11
  • 当访问一个对象的属性时,首先查找这个对象自身有没有改属性
  • 如果没有就查找他的原型(__proto__ 指向的 prototype)
  • 如果还没有查找原型对象的原型 (Object)
  • 一致找到 null 为止

# 扩展内置对象

可以通过原型对象,对原来的内置对象进行扩展自定义的方法

//对原型对象的扩展 , 不推荐使用覆盖重新指向的方法
Array.prototype.sum = function(){
    var sum = 0;
    for(var i = 0;i < this.length;i++){
        sum+=this[i];
    }
    return sum;
}
console.log(arr.sum());
1
2
3
4
5
6
7
8
9

# call()方法

  1. 可以调用函数

    function fn(x,y){
        console.log(x+y);
    }
    fn.call();//调用
    
    1
    2
    3
    4
  2. 可以改变函数的 this 指向

    function fn(x,y){
        console.log(this);
        console.log(x+y);
    }
    var y = {
        name : 'yuadh';
    }
    fu.call(y,3,4);//改变了指向
    
    1
    2
    3
    4
    5
    6
    7
    8

利用call() 函数实现继承属性

function Father(uname,age){
    this.uname = uname;
    this.age = age;
}
function Son(uname,age,score){
    Father.call(this,uname,age);
    this.score = score;
}
var son = new Son('yuadh',21,44);
1
2
3
4
5
6
7
8
9

# 原型对象继承原理

父类的原型对象

Father.prototype.money = function(){
    console.log('make money');
}
1
2
3

子类的原型对象

Son.prototype.exam = function(){
    console.log('examing...');
}
1
2
3

上面实现了属性的继承,但是没有对原型对象 实现继承

Son.prototype = Father.prototype;
1

此解决了子类对父类的原型对象的继承 ,但是父类的原型对象会出现问题

因为指向的是同一内存空间

解决方法

Son.prototype = new Father();
Son.prototype.constructor = Son;
//需要在上两个语句后面添加子类自身的原型对象属性方法,不然会被覆盖
Son.prototype.exam = function(){
    console.log('examing...');
}
1
2
3
4
5
6

因为 Father 的实例化对象里有 __proto__ 属性,且实例化对象对父类原型对象没有影响。对子类的构造方法进行了覆盖,需要将构造函数重新指向子类

# ES5新增方法

  • 数组方法
  • 字符串方法
  • 对象方法

# 数组方法

迭代方法 :

  • forEach()
  • map()
  • filter()
  • some()
  • every()

forEach

array.forEach(function(currentVale,index,arr))
1
  • currentValue 数组当前项的值
  • index 数组当前项的索引
  • arr 数组对象本身

例子使用:

var arr = [1,2,3];
var sum = 0;
arr.forEach(function(value,index,array){
	sum += value;
})
console.log(sum);
1
2
3
4
5
6

filter

array.filter(function(currentVale,index,arr))
1

返回偶数元素的例子

var arr = [12,4,5,7,8];
var newArr = arr.filter(function(value,index){
    return value%2 === 0;
})
console.log(newArr);
1
2
3
4
5

soome

array.some(function(currentVale,index,arr))
1

查找满足条件的元素是否存在 ,存在返回 true 不存在返回 false

var arr = ['yuadh','pink','me'];
var flagx = arr.some(function(value){
    return value == 'yuadh';
})
1
2
3
4

当查询到一个满足条件的元素就会停止循环查找

# 综合使用

<div class="search">
        按照价格查询: <input type="text" class="start"> - <input type="text" class="end"> <button class="search-price">搜索</button> 按照商品名称查询: <input type="text" class="product"> <button class="search-pro">查询</button>
    </div>
    <table>
        <thead>
            <tr>
                <th>id</th>
                <th>产品名称</th>
                <th>价格</th>
            </tr>
        </thead>
        <tbody>


        </tbody>
    </table>
    <script>
        // 利用新增数组方法操作数据
        var data = [{
            id: 1,
            pname: '小米',
            price: 3999
        }, {
            id: 2,
            pname: 'oppo',
            price: 999
        }, {
            id: 3,
            pname: '荣耀',
            price: 1299
        }, {
            id: 4,
            pname: '华为',
            price: 1999
        }, ];
        var tbody = document.querySelector('tbody');
        var search_button = document.querySelector('.search-price');
        var start_text = document.querySelector('.start');
        var end_text = document.querySelector('.end');
        var product = document.querySelector('.product');
        var search_pro = document.querySelector('.search-pro');
        showres(data);

        function showres(data) {
            tbody.innerHTML = "";
            data.forEach(function(value, index) {
                var th = document.createElement('tr');
                th.innerHTML = '<td>' + value.id + '</td><td>' + value.pname + '</td><td>' + value.price + '</td>'
                tbody.appendChild(th);
            })
        }
        search_button.addEventListener('click', function() {
            var newdata = data.filter(function(value) {
                return value.price >= start_text.value && value.price <= end_text.value;
            })
            showres(newdata);
        });
        search_pro.addEventListener('click', function() {
            var newArr = [];
            data.some(function(value) {
                if (product.value == value.pname) {
                    newArr.push(value);
                    return true;
                }
            })
            showres(newArr);
        })
    </script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

# trim

去除字符串两侧空格

var str = '  an  dy';
var newStr = str.trim();
1
2

# Object.keys()

获取对象的属性返回一个数组

var obj = {
    id: 4,
    pname: '华为',
    price: 1999
}
var arr = Object.keys(obj);
arr.forEach(function(value){
    console.log(value);
})
1
2
3
4
5
6
7
8
9

# Object.defineProperty()

Object.defineProperty(obj,prop,descriptor);
1

第三个参数 descriptor 以对象形式 {} 书写

  • value : 设置属性的值,默认值为 undefined

  • writable : 值是否可以重写 , true | false

  • enumerate: 目标属性是否可以被枚举,true | false (是否允许被遍历,默认不能)

  • configurable:目标属性是否可以被删除或是否可以再次修改特性,true | false

    (设置这个属性后不允许删除或修改属性)

编辑 (opens new window)
上次更新: 2023/02/07, 14:51:48
js面向对象1
js面向对象3

← js面向对象1 js面向对象3→

Theme by Vdoing | Copyright © 2021-2023 yuadh
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×