JS--Day24(상속(바인드/적용/호출)

1. 커링 검토

① Currying은 여러 매개변수가 있는 함수를 하나의 부분 매개변수 함수로 바꾸는 것을 의미합니다.

② 카레 기능(도구)의 구현 아이디어:

     1) 원래 함수의 매개변수를 저장하기 위해 특별히 배열을 정의합니다.

     2) 원래 함수의 매개변수(수량)가 부족할 때 함수를 반환(원래 함수의 매개변수를 모으기 위해)

     3) 원래 함수의 매개변수(수량)가 충분하면 원래 함수를 호출합니다.

③코드:

 // 1、原函数:
    function sum(a, b, c, d) {
        return a + b + c + d;
    }
 // 2、柯里化工具函数
    function curry(cb) {
        let arr = [];
        function fn(...args) {
            arr = [...arr, ...args];//收集参数
            if (arr.length < cb.length) {// 函数.length 表示的是函数形参的个数
                return fn;
            } else {
                return cb(...arr);
            }
        }
        return fn;
    }
    // 3、(调用柯里化工具函数)把原函数柯里化
    let cSum = curry(sum);
    // 4、调用柯里化后的函数。
    console.log(cSum(2, 3)(5)(6))
    // console.log(cSum(2)(4)(5)(6))
    // console.log(cSum(2, 4, 5)(6))

④커링의 역할: 함수의 매개변수 값을 재사용할 수 있습니다.
   

 let f01 = cSum(2, 3)(5);// f01是持有 2,3,5的函数
     f01(6);//求 2+3+5 + 6
     f01(7);//求 2+3+5 +7

2. 보충: 클래스 정의

①ES5

// 1)、用构造函数:这种写法,会导致内存中定义了多个相同的函数。浪费了内存
 function Doctor(name,dept){
     this.name = name;
     this.dept = dept;
     // 这种写法,会导致内存中定义了多个相同的函数。浪费了内存。
     this.seatZhen = function(){
         console.log(this.name+"在坐诊………………");
     }
 }
 let d1= new Doctor("宋和叶","神经科");
 let d2 = new Doctor("纪朝锋","精神科");
// 2)、用构造函数结合原型(prototype)定义类
 function Doctor(name,dept){
     this.name = name;
     this.dept = dept;
 }
// 一个构造函数的原型属性上的属性和方法,可以被它的实例共享
 Doctor.prototype.seatZhen =  function(){
     console.log(this.name+"在坐诊………………");
 }
 let d1= new Doctor("宋和叶","神经科");
 let d2 = new Doctor("纪朝锋","精神科");
 d1.seatZhen();
 d2.seatZhen();

② ES6에서

//ES6中用class:class定义类,是个语法糖。
class Doctor{
    constructor(name,dept){
        this.name = name;
        this.dept = dept;
    }
    seatZhen(){
        console.log(this.name+"在坐诊………………");
    }
}
let d1= new Doctor("宋和叶","神经科");
let d2 = new Doctor("纪朝锋","精神科");
d1.seatZhen();
d2.seatZhen();

3. 프로토타입(체인) 상속

// 原型(链)继承,必须用ES5的写法。
// 1、父类
    function Person(name, sex) {
        this.name = name;
        this.sex = sex;
    }
    Person.prototype.eat = function () {
    }
// 2、子类1
    function Doctor(dept) {
        this.dept = dept;
    }
    // 建立继承关系(原型的方式):子类(构造函数)的原型属性 指向 父类的对象(实例)
    Doctor.prototype = new Person("宋和叶", "女");
    let d1 = new Doctor("神经科");
    console.log(d1.name);
    console.log(d1.eat);
    let d1 = new Doctor("神经科");
// 3、子类2
    function Programmer(lanuage){
     this.lanuage = lanuage;
    }
    Programmer.prototype = new Person("纪朝锋","男");
    let p1 = new Programmer("javascript");
    p1.name;
    p1.eat();

4. 프로토타입(체인) 상속 시 유의사항

① 먼저 상속 관계를 완성한 후 서브 클래스 고유의 속성과 메서드를 추가합니다.

② 하위 클래스별 속성 및 메서드 작성 시 다시 프로토타입을 만들 수 없습니다(더 이상 프로토타입을 json 객체에 직접 할당할 수 없음).

// 1、父类
function Person(name,sex,books){
    this.name = name;
    this.sex = sex;
    this.books = books;
}
Person.prototype.eat = function(str){
    console.log(this.name+"在吃"+str+",天在看…………");
}
// 2、子类1
function Doctor(dept){
    this.dept = dept;
}
// 建立继承关系(原型的方式):子类(构造函数)的原型属性 指向 父类的对象(实例)
Doctor.prototype = new Person("宋和叶","女",[]);
Doctor.prototype.seatZhen = function(){
    console.log(this.name+"在坐诊……");
}
// 不能重新prototype属性
// Doctor.prototype = {
//     seatZhen:function(){
//         console.log(this.name+"在坐诊……");
//     }
// }
let d1 = new Doctor("神经科");
d1.name = "纪朝锋";
let d2 = new Doctor("神经科");
d2.name="党艺华";
d1.eat("油条");
d1.seatZhen();
d2.eat("包子");

5. 호출 및 적용 기능

① 전화 신청:

1. 호출과 적용 모두 함수(함수)의 메서드입니다.

2. 호출과 적용 모두 원래 함수를 호출하고 있습니다.

3. 호출 및 적용은 원래 기능에서 이것의 포인트를 변경할 수 있습니다.

4. 호출 및 적용의 첫 번째 매개변수는 원래 함수의 이 지점입니다.

5. 호출은 함수와 객체를 분리할 수 있습니다(결합도: 종속도/연관도. 높은 응집도, 낮은 결합도).

6. 호출과 적용의 차이점(단지 형식의 차이):

      1) 두 번째 매개변수부터 뒤에 오는 호출 함수의 매개변수는 원래 함수의 매개변수입니다.

      2) 적용 함수에는 두 개의 매개변수만 있고 두 번째 매개변수는 배열이며 배열에는 원래 함수의 매개변수가 포함됩니다. 이런 식으로 apply의 두 번째 매개 변수는 인수를 사용할 수 있습니다.

②예제 코드

    let person = {
        name: "张三疯",
        eat: function () {
            console.log(this.name + "在吃");
        }
    }
    person.eat();
    let dog = {
        name: "小黑"
    }
    person.eat.call(dog);
    function eat(str) {
        console.log(this.name + "在吃" + str);
    }
    eat("食物");
    let dog = {
        name: "小黑"
    }
    eat.call(dog, "油泼面");//等价于:dog.eat("油泼面");
    let doctor = {
        name: "张三疯"
    }
    eat.call(doctor, "方便面");//等价于:doctor.eat("方便面");
    eat.apply(doctor, ["油条"])
    3、call和apply的区别
    eat.call(doctor, "方便面");//等价于:doctor.eat("方便面");
    eat.apply(doctor, ["油条"])//等价于:doctor.eat("油条");
    function eat(str, song) {
        console.log(this.name + "吃着" + str + ",唱着" + song);
    }
    let dog = {
        name: "小黑"
    }
    function fn01() {
        console.log("arguments", arguments);
        eat.apply(dog, arguments); 
//  arguments也是函数的内置对象,该对象是个伪数组(不是数组,
//  但是可以使用数组的length,下标),里面存储着函数的实参
    }
    fn01("火锅", "最炫民族风");

6. 함수 호출, 적용, 바인딩

① 바인드와 콜 및 적용의 차이점:

동일한 지점: 바인드, 호출, 적용은 이것의 방향을 바꿀 수 있습니다.

차이점: 1. bind는 원래 함수를 호출하지 않고 새 함수를 생성하며(bind의 반환 값은 새 함수임) 새 함수에서 this가 bind의 개체입니다. bind는 강한 결속이라는 의미를 가지고 있습니다. bind가 호출되는 한 개체와 함수는 영원히 바인딩됩니다. 2. 호출 및 적용은 원래 함수를 호출합니다.  

② 예시:

  function eat(str){
      console.log(this.name+"在吃"+str);
  } 
  let dog = {
    name:"小黑"
  }
  let pig = {
      name:"小白"
  }
// 1)、bind
  let fn01 = eat.bind(dog);//fn01 这个函数,就是dog和eat绑定在一起的函数。只要调用fn01,this必 
  然是dog
  fn01("油泼面");
  fn01("狗粮");
  let fn02 = eat.bind(pig);//fn02 这个函数,就是pig和eat绑定在一起的函数。只要调用fn02,this必 
 然是pig
  fn02("玉米");
  fn02("米饭");
// 2)、call
  eat.call(dog,"油泼面");// 如果希望this是dog,那就call dog
  eat.call(dog,"狗粮");
  eat.call(pig,"玉米");// 如果希望this是pig,那就call pig
  eat.call(pig,"米饭");

7. 호출 및 적용 상속

①하위 클래스 생성자에서 호출과 적용을 사용하여 부모 클래스 생성자에서 이(하위 클래스 객체)를 변경합니다.

② 단점 : 부모 클래스의 프로토타입 속성에 대한 내용(속성 및 메소드) 상속 불가

function Person(name,sex){
    this.name = name;
    this.sex = sex;
}
// Person.prototype.eat = function(str){
//     console.log(this.name+"在吃"+str);
// }
function Doctor(name,sex,dept){
    // apply的继承。
    let obj = this;
    Person.apply(obj,arguments);//没有把所谓的构造函数(Person)当构造函数使用(就当一个普通函数);等价于: this.Person(arguments);
    this.dept = dept;
}
let d1 =new Doctor("宋和叶","女","儿科");
let d2 = new Doctor("纪朝锋","男","骨科");
console.log(d1.name);
console.log(d2.name);
d1.eat("油泼面");

8. 조합 상속

프로토타입(체인) 상속을 호출과 결합하고 상속을 적용합니다. 각자의 강점을 발휘합니다.

① 프로토타입 상속: 부모 클래스의 프로토타입 속성에 대한 내용(속성 및 메서드)을 상속받는다.

②상속 호출 및 적용 : 부모 클래스 생성자의 속성과 메소드를 상속 받습니다.

function Person(name,sex){
    if(arguments.length>0){
        this.name = name;
        this.sex = sex;
    }
}
Person.prototype.eat = function(str){
    console.log(this.name+"在吃"+str);
}
function Doctor(name,sex,dept){
    // call和apply继承:把父类构造函数里的属性和方法继承下来。
    Person.apply(this,arguments);
    this.dept = dept;
}
// 原型继承:把父类原型属性上内容(属性和方法)继承下来。
Doctor.prototype = new Person();
let d1 =new Doctor("宋和叶","女","儿科");
let d2 = new Doctor("纪朝锋","男","骨科");
console.log(d1.name);
console.log(d2.name);
d1.eat("油泼面");

9. ES6의 상속

 ①상속 관계의 키워드: 확장하다;

 ② super()는 서브클래스 생성자에서 호출되어야 하며, 서브클래스 생성자의 첫 번째 문장에 작성되어야 한다.

 ③ ES6의 이런 표기법은 문법적 설탕(필기법을 바꿈, 본질은 같다)

class Person{
    constructor(name,sex){
        this.name = name;
        this.sex = sex;
    }
    eat(str){
        console.log(this.name+"在吃"+str);
    }
}
// extends关键字完成继承关系
class Doctor extends Person{
    constructor(name,sex,dept){
        // super就是父类
        super(name,sex);//这就相当于调用了父类的构造函数。这句话必须放在子类构造函数里的第一句话
        this.dept = dept;
    }
}
let d1 =new Doctor("宋和叶","女","儿科");
let d2 = new Doctor("纪朝锋","男","骨科");
console.log(d1.name);
console.log(d2.name);
d1.eat("油泼面");

10. (확장) ES6 구문 슈가 검증

 function Person(name, sex) {
        if (arguments.length > 0) {
            this.name = name;
            this.sex = sex;
            // this.eat = function(str){
            //     console.log(this.name+"在吃"+str);
            // }
        }
    }
    Person.prototype.eat = function (str) {
        console.log(this.name + "在吃" + str);
    }
    function Doctor(name, sex, dept) {
        Person.apply(this, arguments);
        this.dept = dept;
    }
    // Doctor.prototype = new Person();
    let d1 = new Doctor("宋和叶", "女", "儿科");
    let d2 = new Doctor("纪朝锋", "男", "骨科");
    console.log(d1.eat === d2.eat);//如果把eat方法写在构造函数里,那么是false(因为,每次调用构造函数,都会重新定义函数) )
    console.log(d1.eat === d2.eat);//如果把eat方法写在原型属性上,那么是true

11. (확장) 정식 클래스의 상속관계를 보라.

①js 언어 자체의 클래스 상속 관계

  console.dir(Array);
//继承关系: Array ---> Function --> Object  
  let arr = new Array(10);      
  console.dir(arr);
  console.log(arr.__proto__ == Array.prototype);

②dom 객체가 속한 클래스와 그 상속 관계

  let box =  document.getElementById("box"); //box对象是 类 HTMLDivElement 的实例
  console.dir(box);
  div是 HTMLDivElement的对象,即就是: div属于 HTMLDivElement 类型。
  继承关系: HTMLDivElement--> HTMLElement-->Element-->Node-->EventTarget-->Object
  console.log(box.constructor===HTMLDivElement);
  let t = document.createElement("div");
  let t2 = new HTMLDivElement();//不行, 因为 HTMLDivElement,不是真正的构造函数,实际是个接口

01. 프로토타입 상속의 개략도

02. 호출 및 적용 상속의 개략도

 

 

Supongo que te gusta

Origin blog.csdn.net/weixin_72756818/article/details/129861822
Recomendado
Clasificación