类和对象

133 阅读4分钟

1-创建类和对象(ES6)

 <script>
    // 通过class 关键词创建一个类,类名习惯性首字母大写
    class Person {
    // 类中有constructor 函数,可以同接收参数  constructor 相当于之前学习的构造函数!!!!
    // 添加方法
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        
         // 给类添加方法, 不需要写function, 函数和函数之间不能加逗号
        run() {
            console.log("跑步5w圈!!!")
        }

        jump() {
            console.log("....")
        }
    }
    // 生成实例,使用new关键词!!!
    var ldh = new Person("刘德华", 50)
    var lyf = new Person("刘亦菲", 30)
    console.log(ldh)
    console.log(lyf)
   
</script>

2-类的继承

<script>
    class Father {
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }
        sum() {
            console.log(this.x + this.y)
        }
    }

    // extends 继承!!!
    class Son extends Father{
        constructor(x, y) {
            super(x, y) // 调用了父类中的构造函数!!!
            //相当于  this.x = x; this.y = y;
           
        }
        // static  如果加上static 那么这个属性或者方法就是类上面的
         sub() {
            console.log(this.x - this.y)
        }
        //  static sub() {
            // console.log(this.x - this.y)
       //  }
    }

    var s1 = new Son(10, 5)
    s1.sum();
    s1.sub();
</script>

3-创建对象

    1.创建对象方式一 : 字面量
     var obj = {}
     
    2.创建对象方式二 : 构造函数
     function Person() {}
     new Person()
     
    3.创建对象方式三 : Object
     var obj = new Object()
     obj.
     
例:使用构造函数来定义类
function Person(name, age) {
        this.name = name;
        this.age = age;
        this.run = function() {
            console.log("1111")
        }
        
         new代表以下内容,所以这里的this代表的是obj
                // var obj = {}
                // obj.name = name;
                // obj.age = age;
                // obj.run = function() {
                //     console.log("/...")
                // }
                // return obj;
        
    }
    // p1就是一个实例化出来的对象!!!
    var p1 = new Person("郭富城", 50)
    var p2 = new Person("郭富城", 50)
    // 执行函数一次,里面的this发生变化,就是实例化出来的对象,这里this代表的是p1,p2,p3,
    var p3 = new Person("郭富城", 50)
    console.log(p1)

4-原型对象

  <script>
    function Person(name, age) {
        this.name = name;
        this.age = age
    }
    // 在Person的原型对象中增加方法或者属性,那么这个方法或者属性就是所有实例对象所共享的!!!
    // str.indexOf str.includes... 字符串类型不是对象类型。字符串是一个对象!!!
    Person.prototype.run = function() {
        console.log("这是一个run函数!!!")
    }

    // console.log(Person.prototype) // 这就是构造函数的原型对象!!!
    var p1 = new Person("dehua", 20)
    var p2 = new Person("zhangsan", 30)
    console.log(p1.run === p2.run) // true //如果不使用原型对象,则这两个值是分别调用的,需要调用两次,且不相等
</script>

5-原型链

 例:
<script>
    function Person(name, age) {
        this.name = name;
        this.age = age
    }

    Person.prototype.run = function() {
        console.log("这是一个run函数")
    }
    // Person函数中包括name ,age , prototype代表原型对象
    // prototype原型对象中包括run方法和 constructor构造器
    // constructor 又代表Person函数
    // 三角关系
    //其中下方实例对象中包括name ,age , _ _proto_ _ (这个_ _proto_ _也指代原型对象)
    // console.log(p1.run)
    console.log(Person.prototype)
    console.log(Person.prototype.constructor) // constructor: 构造器!!!

    var p1 = new Person("zhangsan", 20)
    console.log(p1)
</script>

6-对象上属性成员查找规则

  <script>
    function Person(name, age) {
        this.name = name;
        this.age = age
    }
    // Person.prototype.sex = "man"
    // 这样可以把sex属性放到了原型对象上!!!

    var p1 = new Person("lisi", 20)
    p1.sex = "man"
    // delete p1.sex  // 删除对象中属性或者方法!!!
    console.log(p1.sex) // 查找顺序,先查找该实例对象上是否有该属性!!! 如果没有就在查找__proto__,如果再原型对象中查找不到,就是undefined
</script>

例2:
 <script>
    // 在原型对象上增加的方式能共享给所有的实例对象!!!
    Array.prototype.sum = function() {
        var sum = 0;
        for(var i = 0; i < this.length; i++) {
            sum += this[i]
        }
        return sum;
    }

    // var arr = new Array(1, 2, 3)
    var arr = [1, 2, 3]
    console.log(arr.sum())
</script>

7-改变this指向

 <script>
//console.log(this)    //这里this指代window
//    setTimeout(function() {
//        console.log(this)  //这里this指代window
//    })
var obj = {
    name: "kuaixiang"
}
function fn(x, y) {
    console.log(this.name)
    console.log(x + y)
}
// fn()

方法1: 使用call方法进行改变this指向
 fn.call(obj, 1, 2) // 1 2 为参数值
 // 相当于fn() 但是有区别,call可以改变fn函数里面的 this指向!!!
// call方法可以传递参数,第一个为你要改变this指向为谁!!!这里将this本来指代window改为obj

方法2: 使用apply方法进行改变this指向
fn.apply(obj, [1, 2])   // apply与call方法类似,都可以改变this的指向!!!区别只有参数传递的时候为数组形式。

方法3: 使用bind方法进行改变this指向
 var newFn = fn.bind(obj, 1, 2)    //bind 绑定的意思          bind方法执行,不会直接调用fn函数 ,bind方法会返回一个新的函数!!!
    // 新的函数里面的this已经发生了变化!!!

ES5中构造函数的继承

  <script>
    function Father(name, age) {
        this.name = name;
        this.age = age
    }
    Father.prototype.run = function() {
        console.log("father runrunrun!!!")
    }

   
    function Son(name, age, score) {
        方法1: Father.call(this, name ,age)
        // 这句话的意思是将Father里的this指向改为son里的this就相当于  // this.name = name this.age = age
         // 通过使用call的方式进行继承!!!但他的缺点是不能继承原型对象里的函数
        this.score = score;
    }
    
     方法2: Son.prototype = new Father();
     // 通过将Father实例赋值给Son的原型对象。虽然name和age继承过来了,但是它不能进行初始化!!!就是不能用于实例对象中
     
     //所以一般将他们放在一起使用
     
    var s1 = new Son("xiaosi", 20, 100);
    console.log(s1.name)
    s1.run() // 
</script>