1.构造函数和原型

  在ES6之前,对象不是基于类创建的,而是用一种成为构建函数的特殊函数来定义对象和它们的特征

  • 创建对象的方式
    • 对象字面量
    • new Object()
    • 自定义构造函数
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>利用构造函数创建对象</title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             /* 
10                 在JS中,使用构造函数要注意
11                     -构造函数用于创建某一类对象,其首字母要大写
12                     -构造函数要和new一起使用才有意义
13                 构造函数是一种特殊的函数,主要用来初始化对象
14              */
15             //1.利用new Object创建对象
16             var obj1 = new Object();
17             //2.利用对象字面量创建对象
18             var obj2 = {};
19             //3.利用构造函数创建对象
20             function Star(uname,age){
21                 this.uname = uname;
22                 this.age = age;
23                 this.sing = function(){
24                     console.log("Monroe");
25                 }
26             }
27             var singer = new Star("bbh",30);
28             console.log(singer);
29             singer.sing();
30         </script>
31     </body>
32 </html>
  • 静态成员和实例成员
    • 静态成员:在构造函数本上添加的成员称为静态成员,只能由构造函数本身访问
    • 实例成员:在构造函数内部创建的对象称为实例成员,只能由实例化对象来访问
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function Star(uname,age){
10                 this.uname = uname;
11                 this.age = age;
12                 this.sing = function(){
13                     console.log("Monroe");
14                 }
15             }
16             var singer = new Star("bbh",30);
17             //1.实例成员就是构造函数内部通过this添加的成员 uname,age,sing就是实例成员
18             //实例成员只能通过实例化的对象来访问
19             singer.sing();
20             //2.静态成员 在构造函数本身添加的成员
21             Star.sex = "";
22             //静态成员只能通过构造函数来访问
23             console.log(Star.sex);//
24             console.log(singer.sex);//undefined
25         </script>
26     </body>
27 </html>
  • 原型:prototype

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

  JS规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个prototype就是一个对象,它的所有属性和方法都会被构造函数所拥有,我们可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function Star(uname,age){
10                 this.uname = uname;
11                 this.age = age;
12                 // this.sing = function(){
13                 //     console.log("Monroe");
14                 // }
15             }
16             Star.prototype.sing = function(){
17                 console.log("Monroe");
18             };
19             var singer = new Star("bbh",30);
20             // console.dir(Star);
21             singer.sing();
22             //一般情况下我们的公共属性定义到构造函数里面,公共的方法放到原型对象上
23         </script>
24     </body>
25 </html>
  • 对象原型

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

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>对象原型</title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function Star(uname,age){
10                 this.uname = uname;
11                 this.age = age;
12             }
13             Star.prototype.sing = function(){
14                 console.log("Monroe");
15             };
16             var singer = new Star("bbh",30);
17             console.log(singer);//在对象身上系统自动添加了一个__prototype__属性,指向我们构造函数的原型对象prototype
18             console.log(singer.__proto__===Star.prototype);//true
19             //方法的查找规则:首先看singer对象上是否有sing方法,如果有就执行对象上的sing
20             //如果没有,就去构造函数的原型对象prototype上查找该方法
21         </script>
22     </body>
23 </html>
  • constructor构造函数

   对象原型(__proto__)和构造函数(prototype)原型对象里面都有一个属性constructor,我们称之为构造函数,因为它指回构造函数本身。用来记录该对象引用与哪个构造函数,它可以让原型对象重新指向原来的构造函数

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>对象原型</title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function Star(uname,age){
10                 this.uname = uname;
11                 this.age = age;
12             }
13             //很多情况下,我们需要利用constructor指回原来的构造函数
14             // Star.prototype.sing = function(){
15             //     console.log("Monroe");
16             // };
17             Star.prototype = {
18                 //如果我们修改了原来的原型对象,给原型对象赋值的是一个对虾干,则必须手动利用constructor
19                 //指回原来的构造函数
20                 constructor:Star,
21                 sing:function(){
22                     console.log("Monore");
23                 },
24                 dance:function(){
25                     console.log("solo");
26                 }
27             }
28             var singer = new Star("bbh",30);
29             console.log(Star.prototype);
30             console.log(singer.__proto__);
31         </script>
32     </body>
33 </html>
  • 构造函数实例和原型对象三角关系

  •  原型链

 

 

 

  • JavaScript成员查找机制
    • 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性
    • 如果没有就查找它的原型(也就是__proto__指向的prototype原型对象)
    •  如果还没有就查找原型对象的原型(Object的原型对象)
    • y依次类推一直找到Object为止(null)\
  • 原型对象的this指向
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             function Star(uname,age){
10                 this.uname = uname;
11                 this.age = age;
12             }
13             var that;
14             Star.prototype.sing = function(){
15                 that = this;
16                 console.log("lalalalalala");
17             }
18             var singer = new Star("lala",18);
19             //1.在构造函数中里面的this指向的是对象实例singer
20             singer.sing();
21             console.log(that === singer);//true
22             //2.原型对象函数里面的this指向的是实例对象singer(调用之后才有指向)
23         </script>
24     </body>
25 </html>
  • 扩展内置对象

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

  注意:数组和字符串内置对象不能给原型对象覆盖操作Array.prototype={},只能是Array.prototype.xxx=function(){}

 

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //原型对象的应用,扩展内置对象的方法
10             console.log(Array.prototype);
11             Array.prototype.sum = function(){
12                 var count = 0;
13                 for(var i = 0 ; i < this.length ; i++){
14                     count += this[i];
15                 }
16                 return count;
17             }
18             var arr = [1,2,3];
19             console.log(arr.sum());//6
20             console.log(Array.prototype);
21         </script>
22     </body>
23 </html>

2.继承

  ES6之前没有给我们提供extends继承,我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承

  • call()
    • 调用这个函数,并且修改函数运行时的this指向
    • fun.call(thisArg,arg1,arg2…)
      • thisArg:当前调用函数this的指向对象
      • arg1、arg2:传递的参数
  • 利用父构造函数继承属性
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //利用父构造函数继承属性
10             //1.父构造函数
11             function Father(uname,age){
12                 //this指向父构造函数的对象实例
13                 this.uname = uname;
14                 this.age = age;
15             }
16             //2.子构造函数
17             function Son(uname,age){
18                 //this指向子构造函数的对象实例
19                 Father.call(this,uname,age);
20             }
21             var son = new Son("bbt",16);
22             console.log(son);
23         </script>
24     </body>
25 </html>
  • 借用原型对象继承父亲类型方法
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //利用父构造函数继承属性
10             //1.父构造函数
11             function Father(uname,age){
12                 //this指向父构造函数的对象实例
13                 this.uname = uname;
14                 this.age = age;
15             }
16             Father.prototype.money = function(){
17                 console.log("花钱");
18             }
19             //2.子构造函数
20             function Son(uname,age){
21                 //this指向子构造函数的对象实例
22                 Father.call(this,uname,age);
23             }
24             //Son.prototype = Father.prototype;这样直接赋值会有问题
25             //如果修改了子原型对象,父原型对象也会一起变化
26             Son.prototype = new Father();
27             //如果利用对象的形式修改了原型对象,利用constructor指回原来的构造函数
28             Son.prototype.constructor = Son;
29             var son = new Son("bbt",16);
30             console.log(son);
31         </script>
32     </body>
33 </html>

  ES6之前通过构造函数+原型对象实现面向对象编程

  ES6通过类实现面向对象编程

  • 类的本质
    • 类的本质还是function
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //ES6中的类实际上就是语法糖
10             //所谓语法糖,就是一种便捷写法
11             class Star {
12                 
13             }
14             console.log(typeof Star);
15             //1.类的本质其实还是一个函数,我们也可以简单的认为类就是构造函数的另外一种写法
16             //(1)类由原型对象prototype
17             console.log(Star.prototype);
18             //(2)类原型对象的constructor指向类本身
19             console.log(Star.prototype.constructor);
20             //(3)类可以通过原型对象添加方法
21             Star.prototype.sing = function(){
22                 console.log("lalalalalala");
23             }
24             console.log(Star.prototype);
25             //(4)类的实例的对象原型指向类的原型对象
26             var singer = new Star();
27             console.log(singer.__proto__ === Star.prototype);//true
28         </script>
29     </body>
30 </html>

3.ES5中新增的方法

  • 数组方法
    • 迭代方法:forEach()、map()、filter()、some()、every()
      • forEach(function(currentValue, index, arr))
        • currentValue:数组当前项的值
        • index:数组当前项的索引
        • arr:数组对象本身
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //forEach迭代(遍历)数组
10             var arr = [1,2,3];
11             var sum  =0;
12             arr.forEach(function(value,index,arr){
13                 console.log('每个数组元素'+value);
14                 console.log('每个数组元素的索引号'+index);
15                 console.log('数组本身'+arr);
16                 sum += value;
17             })
18             console.log(sum);
19         </script>
20     </body>
21 </html>
      • array.filter(function(currentValue,index,arr){})
        • filter()方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,主要用于筛选数组
        • 注意它直接返回一个数组
        • currentValue:数组当前项的值
        • index:数组当前项的索引号
        • arr:数组对象本身
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             var arr = [12,56,6,88];
10             var newArr = arr.filter(function(value,index,arr){
11                 return value > 20;
12             })
13             console.log(newArr);
14         </script>
15     </body>
16 </html>
      • array.some(function(value,index,arr){})
        • some()方法用于检测数组中的元素是否满足指定条件
        • 注意它返回的是布尔值,如果查找到这个元素,就返回true,反之则返回false
        • 如果找到第一个满足条件的元素,则终止循环,不再继续查找
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //some查找数组中是否有满足条件的元素
10             var arr = [56,4,7,28];
11             var res = arr.some(function(value,index,arr){
12                 return value>20;
13             })
14             console.log(res);
15         </script>
16     </body>
17 </html>
    • 查询商品案例
  1 <!DOCTYPE html>
  2 <html>
  3     <head>
  4         <meta charset="utf-8">
  5         <title></title>
  6         <style>
  7             * {
  8                 padding: 0;
  9                 margin: 0;
 10             }
 11 
 12             .box {
 13                 margin: 20px auto;
 14                 width: 554px;
 15                 height: 400px;
 16             }
 17 
 18             .search input {
 19                 display: inline-block;
 20                 width: 50px;
 21             }
 22 
 23             .product {
 24                 margin-top: 10px;
 25             }
 26 
 27             td,
 28             table {
 29                 border: 1px solid #000000;
 30                 border-collapse: collapse;
 31             }
 32             
 33             table {
 34                 width: 400px;
 35                 margin: 0 auto;
 36             }
 37             
 38             .product td {
 39                 text-align: center;
 40                 height: 30px;
 41             }
 42             
 43             .hide {
 44                 display: none;
 45             }
 46         </style>
 47     </head>
 48     <body>
 49         <div class="box">
 50             <div class="search">
 51                 按照价格查找:
 52                 <input class="low" type="text" />-
 53                 <input class="top" type="text" />
 54                 <input class="price" type="button" value="搜索" />
 55                 按照商品名称查找:
 56                 <input class="name" type="text" />
 57                 <input class="info" type="button" value="查询" />
 58             </div>
 59             <div class="product">
 60                 <table cellspacing="0" >
 61                     <thead>
 62                         <tr>
 63                             <td>id</td>
 64                             <td>产品名称</td>
 65                             <td>价格</td>
 66                         </tr>
 67                     </thead>
 68                     <tbody>
 69                         <tr>
 70                             <td>1</td>
 71                             <td>小米</td>
 72                             <td>3999</td>
 73                         </tr>
 74                         <tr>
 75                             <td>2</td>
 76                             <td>oppo</td>
 77                             <td>999</td>
 78                         </tr>
 79                         <tr>
 80                             <td>3</td>
 81                             <td>荣耀</td>
 82                             <td>1299</td>
 83                         </tr>
 84                         <tr>
 85                             <td>4</td>
 86                             <td>华为</td>
 87                             <td>1999</td>
 88                         </tr>
 89                     </tbody>
 90                 </table>
 91             </div>
 92         </div>
 93     </body>
 94     <script type="text/javascript">
 95         //1.按照价格查询
 96         var price = document.querySelector(".price");
 97         var info = document.querySelector(".info");
 98         var trs = document.querySelectorAll(".product tr");
 99         price.onclick = function(){
100             var low = document.querySelector(".low").value;
101             var top = document.querySelector(".top").value;
102             if(low == ''){
103                 low = Number.MIN_VALUE;
104             }
105             if(top == ''){
106                 top = Number.MAX_VALUE;
107             }
108             trs.forEach(function(value,index,arr){
109                 if(index > 0){
110                     if(+value.children[2].innerText > top || +value.children[2].innerText < low){
111                         value.className = 'hide';
112                     }else{
113                         value.className = '';
114                     }
115                 }
116             })
117         }
118         //2.按照商品名字查询
119         info.onclick = function(){
120             var name = document.querySelector(".name").value;
121             if(name === ''){
122                 trs.forEach(function(value){
123                     value.className = '';
124                 })
125             }else{
126                 trs.forEach(function(value,index){
127                     if(index > 0){
128                         value.className = 'hide';
129                         if(value.children[1].innerText.includes(name)){
130                             value.className = '';
131                         }
132                     }
133                 })
134             }
135         }
136     </script>
137 </html>
    • some和forEach的区别
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             var arr  = ['red','orange','yellow','green','blue','purple'];
10             //1.forEach迭代 遍历
11             // arr.forEach(function(value,index,arr){
12             //     if(value === 'green'){
13             //         //在forEach里面return不会终止迭代
14             //         console.log("找到该元素");
15             //     }
16             // })
17             
18             //2.some循环
19             arr.some(function(value,index,arr){
20                 if(value === 'green'){
21                     //在some里遇见return true就是终止遍历 迭代
22                     console.log("找到该元素");
23                     return true;
24                 }
25                 console.log(22);
26             })
27         </script>
28     </body>
29 </html>
  • 字符串方法
    • str.trim()方法会从一个字符串两侧删除空白字符,该方法不影响原字符串本身,它返回的是一个新的字符串
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //trim方法去除字符串两端空格,并返回一个新的字符串
10             var str = "            BBH              ";
11             console.log(str);
12             var res =  str.trim();
13             console.log(res);
14         </script>
15     </body>
16 </html>
  • 对象方法
    • Object.keys()用于获取对象自身所有的属性
      • 效果类似for…in…
      • 返回一个由属性名组成的数组
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //用于获取对象自身的所有属性
10             var obj = {
11                 id: 1,
12                 pname: "小米",
13                 price: 1999,
14                 num: 2000
15             };
16             var arr = Object.keys(obj);
17             console.log(arr);
18         </script>
19     </body>
20 </html>  
    • Object.defineProperty()定义新属性或修改原有属性,3个参数无法省略
      • Object.defineProperty(obj,prop,descriptor)
        • 第三个参数,以对象形式书写
        • value:设置属性的值,默认为undefined
        • writable:值是否可以重写。默认是false
        • enumerable:目标属性是否可以被枚举。默认为false
        • configurable:目标属性书否可以被删除或是否可以再次修改特性,默认为false
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title></title>
 6     </head>
 7     <body>
 8         <script type="text/javascript">
 9             //Object.defineProperty()定义新属性或修改原有的属性
10             var obj = {
11                 id: 1,
12                 pname: "小米",
13                 price: 1999,
14             };
15             //1.以前的对象添加或修改属性的方式
16             // obj.num = 1000;
17             // console.log(obj);
18             //2.Object.defineProperty(obj,prop,descriptor)定义新属性或修改原有的属性
19             //prop如果存在,则是修改属性,不存在则是添加属性
20             Object.defineProperty(obj,'num',{
21                 value: 1000,
22                 //不允许修改这个值
23                 writable: false,
24                 //如果值为false,则不允许遍历,默认为false
25                 enumerable: false,
26                 //如果值为false,则不允许被删除或是再次修改特性,默认是false
27                 configurable: false
28             })
29             obj.num = 2000;
30             console.log(obj);
31             console.log(Object.keys(obj));
32             delete obj.num;
33             console.log(obj);
34             //不能再次修改 报错:Cannot redefine property: num
35             // Object.defineProperty(obj,'num',{
36             //     writable: true
37             // });
38             
39         </script>
40     </body>
41 </html>
版权声明:本文为Miraitowa56原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Miraitowa-fan/p/16162670.html