JavaScript高级第一天

90 阅读6分钟

JavaScript高级

1.面向对象编程介绍

  1. 面对过程
    1. 优点:性能比面向对象高,适合跟硬件联系很紧密 的东西,例如单片机就采用的面向过程编程。
    2. 缺点:没有面向对象易维护、易复用、易扩展
  2. 面向对象
    1. 优点:易维护、易复用、易扩展,由于面向对象有 封装、继承、多态性的特性,可以设计出低耦合的 系统,使系统更加灵活、更加易于维护
    2. 缺点:性能比面向过程低

举例:用面向过程的方法写出来的程序是一份蛋炒饭,而用面向对象写出来的程序是一份盖浇饭。

2.创建类

class Star{
	constructor(uname){
		this.uname = uname
	}
}
var zs = new Star('张三');
console.log(ldh.uname)
(1) 通过class关键字创建类,类名我们还是习惯性定义首字母大写
(2)类里面有个constructor函数,可以接受传递过来的参数,同时返回实例对象
(3) constructor 函数只要new生成实例时,就会自动调用这个函数,如果我们不写这个函数,类
也会自动生成这个函数
(4) 生成实例new 不能省略
(5)最后注意语法规范,创建类类名后面不要加小括号,生成实例类名后面加小括号,构造函数不需要加function

2.在类中添加方法

class Star{
	constructor(uname){
		this.uname = uname
	}
    sing(song){
        console.log(this.uname + song)
    }
}
var zs = new Star('张三');
console.log(ldh.uname)

//调用方式
zs.sing('大佬') //张三大佬

3.继承

class Star{
	constructor(a,b){
		this.a=a
        this.b=n
	}
    sum(a,b){
        console.log(a+b)
    }
    sang(){
        console.log('fulei')
    }
}
var zs = new Star(1,23);
//调用方式
zs.sing('大佬') //张三大佬

//继承
class Sum extends Star{
   constructor(a,b){
		super(a,b)
	}
    sang(){
        console.log(super.sang())//调用父类的sang
    }
}

var son = new Sum(1,2)
son.sum() 
//extends 继承  
//super(a,b)给父传参 必须要放在this之前	  
//super.sang() 调用父类方法
 

4.静态属性和实例成员

class Star{
	constructor(uname){
		this.uname = uname
	}
}
var zs = new Star('张三');
//构造函数里面通过this添加的都是实例成员
console.log(ldh.uname)
//静态成员 在构造函数本身上添加的成员
Star.sex = '男'
//静态成员只能通过函数本身来访问
console.log(Star.sex)

5.原型与原型链(重点)

5.1prototype原型

      class Star {
        constructor(uname) {
          this.uname = uname;
        }
        sing(){
            console.log("打官司")
        }
      }
      var zs = new Star("张三"); 
      var ls = new Star('李四')
      zs.sing()
      ls.sing()//这样子会很浪费内存

	//所以sing方法不应该放构造函数里面

上面这样子会很浪费内存 因为sing会重新开辟一个空间

所以sing方法不应该放构造函数里面

      class Star {
        constructor(uname) {
          this.uname = uname;
        }
      }
      Star.prototype.sing = function () {
        console.log("打官司");
      };
      var zs = new Star("张三");
      var ls = new Star("李四");
      zs.sing();
      ls.sing();

总结prototype原型

原型就是原型对象

  1. 每个构造函数里面都有的对像 主要是为了共享方法
  2. 一般情况下,我们的公共属性定义到构造函数里面,公共的方法我们放到原型对象身上

5.2 _proto_

对象身上系统自己添加一个__proto__指向我们构造函数的原型对象prototype

// 方法的查找规则: 首先先看对象身上是否有某个方法,如果有就执行这个对象上的方法 //如果没有这个方法,因为有_ proto_的存在,就去构造函数原型对象prototype身上去查找这个方法

5.3 原型对象使用对象赋值

      class Star {
        constructor(uname) {
          this.uname = uname;
        }
      }
Star.prototype = {
	//如果使用对象赋值方法需要使用 constructor:来指回原来的构造函数
	constructor: Star,
	sing: function () {
  		console.log("打官司");
	},
	moveto: function () {
    	onsole.log("直接无罪");
	},
};
      var zs = new Star("张三");
      var ls = new Star("李四");
      console.log(Star.prototype);
      console.log(zs.__proto__);
      console.log(Star.prototype.constructor);
      console.log(zs.__proto__.constructor);

5.4构造函数、实例、原型对象三角恋

1662564362716.png

5.5 原型链

1662602738894.png

6.call方法

​ call()可以改变this的指向

        function all (a,b){
            console.log(this)
            console.log(a+b)
        }
        var o = {
            name: "and"
        }

        all(3,4)
        //call()可以改变this的指向 这里让他指向o
        all.call(o,5,3)

借用父结构函数

1.传值

   function Father(uname,password){
      this.uname =uname
      this.password = password
  }
  function Son (uname,password){
  		//父级调用call 让父级的this 指向sub的this
		Father.call(this,uname,password)
  }
  var son =new Son('ldh',123456)
  console.log(son.password)

2.传方法

//让子类的prototype 指向一个新的构造函数(Father)
Son.prototype = new Father( );
//如果利用对象的形式修改了原型对象,别忘了利用constructor指回原来的构造函数
Son.prototype.constructor = Son;

7.类与构造函数的本质

// ES6之前通过构造函数+原型实现面向对象编程
// (1) 构造函数有原型对象prototype
// (2) 构造函数原型对象prototype 里面有constructor 指向构造函数本身
//(3)构造函数可以通过原型对象添加方法
// (4) 构造函数创建的实例对象有__ proto__ 原型指向构造函数的原型对象
// ES6通过类实现面向对象编程
//(1) 类有原型对象prototype
// (2) 类原型对象prototype 里面有constructor 指向类本身
//(3)类可以通过原型对象添加方法
// (4) 类创建的实例对象有__ proto__ 原型指向类的原型对象
//(5)类就是构造函数的语法糖
//语法糖:就是更简洁 版本加一

8.ES5中新增的方法

8.1 数组方法

迭代遍历方法:

  1. forEach()

    	 var arr = [1,3,4]
         var num = 0;
         arr.forEach(function(value,index,array){
            console.log('每个组元素'+value)
            console.log('元素下标'+index)
            console.log('数组本身元素'+array)
             num += value
          })
            console.log(num)
    
  2. map()

  3. filter()

    filter也是查找满足条件的元素返回的是个数组而且是把所有满足条件的元素返回回来

    注意返回是一个新数组需要用参数接收

    var arr = [1,3,4,92,2,99]
    //筛选数组
    var newArr =arr.filter(function(value,index,array) {
    // console.log('每个组元素'+value)
    // console.log('元素下标'+index)
    // console.log('数组本身元素'+array)
         return value >= 9
    })
        console.log(newArr)
    
  4. some()

    检查数组里面是否有符合条件的数据 有就返回true没有就false

          var arr = [1, 3, 4, 92, 2, 99];
          //筛选数组
          var flag = arr.some(function (value, index, array) {
            // console.log('每个组元素'+value)
            // console.log('元素下标'+index)
            // console.log('数组本身元素'+array)
            return value >= 9;
          });
          console.log(flag);
    
  5. every()

数组方法总结

forEach 和 map 用法一样 some和every一样

1.filter也是查找满足条件的元素返回的是个数组而且是把所有满足条件的元素返回回来

2.some也是查找满足条件的元素是否存在返回的是一个布尔值如果查找到第个满足条件的元素就终止循环

注意:如果查询一个元素就用some 因为遇到return会直接退出 forEach和filter 就算找到元素遇到return也不会停止

字符串方法

  1. trim()方法会从一个字符串的两端删除空白字符 trim()方法并不影响原字符串本身,它返回的是一个新的字符串

对象方法

Object.defineProperty()

定义新属性或修改原有的属性。

Object.defineProperty(obj,prop,descriptor)
obj 修改的对象名
prop 属性名

Object.defineProperty()
第三个参数descriptor说明:以对象形式{}书写
value: 设置属性的值默认为undefined
writable: 值是否可以重写。true | false默认为false
//enumerable false不允许被遍历
enumerable: 目标属性是否可以被枚举。true | false默认为false
//configurable  false不允许被删除 而且不能重新修改特性
configurable:目标属性是否可以被删除或是否可以再次修改特性true | false默认为false

Object.keys()

  1. Object.keys() 用于获取对象自身所有的属性
Object.keys(obj) obj(对象名) 

返回一个由属性名组成的数组

单词(重点)

prototype 原型

构造函数.prototype

_proto_ 原型

对象._proto_

constructor

原型里都有constructor这个属性 主要记录该对象引用哪个构造函数 他可以让原型对象指向原来的构造函数

Object.defineProperty(obj,prop,descriptor)