JS 高级特性

2021-09-29  本文已影响0人  甄子健
什么是对象
什么是面向对象

面向对象与面向过程对比

面向对象的特性

总结

面向对象的设计思想
创建对象的几种方法
    // 简单方式 new Object()
    var person = new Object();
    person.name = "tin";
    person.age = 18;
    person.sayName = function() {
        console.log(this.name)
    }
    // 对象字面量化简
    var person = {
        name: "tin",
        age = 19,
        sayName : function(){
            console.log(this.name)
        }
    }
    // 工厂函数
    function createPerson(name,age){
        //添加一个新对象
        var person = new Object();
        person.name = name;
        person.age = age;
        person.sayName = function(){
            console.log(this.name);
        }
        // 必须有返回值
        return person
    }
    //生产真正的对象
    var person1 = createPerson("bob",17);
    var person2 = createPerson("tin",18);
    // 自定义构造函数
    function Person(name,age){
        this.name = name;
        this.age = age;
        this.sayName = function(){
            console.log(this.name)
        }
    }

    // 生成对象实例
    var person1 = new Person("tin",19);
    var person2 = new Person("bob",18);

    person1.sayName();
    person2.sayName();

new 关键字的用途
1 创建一个新对象
2 将函数内部的 this 指向这个新对象
3 执行构造函数内部的代码
4 将新对象作为返回值
通过构造函数生成的实例是可以找到自己当初的构造函数的
constructor 属性 构造器 构造函数
每个对象的 constructor 属性值就是生成这个对象的构造函数
判断一个对象的具体类型,需要使用 instance of 进行判断

构造函数和实例对象的关系

静态成员和实例成员

构造函数的问题

    // 解决办法1:将公共的函数提取到构造函数之外
    function sayName(){
        console.log(this.name);
    }
    // 解决办法2:将多个公共的函数封装到一个对象
    var fns = {
        sayName: function(){
            console.log(this.name);
        },
        sayAge: function(){
            console.log(this.age)
        }
    }

原型对象

prototype 原型对象

    // 定义构造函数
    function Person(name,age){
        this.name = name;
        this.age = age;
    }
    // 获取构造函数的 prototype 属性
    console.log(Person.prototype);
    // 属性值是一个对象,通常叫做原型对象
    // 对象内部可以添加一些属性和方法
    Person.prototype.type = "human";
    Person.prototype.sayHi = function(){
        console.log("hello");
    };

    // 构造函数的原型对象上面都默认有一个 constructor 属性
    console.log(Person.prototype.constructor);

    // 创建实例对象
    var p1 = new Person("mike",19);
    // 所有对象都有一个 _proto_ 的属性,是一个指针,指向的就是生成实例对象的原型对象
    console.log(p1._proto_)

    // _proto_ 属性并不是一个标准的属性,是浏览器自己根据语法自动生成
    // 在真正的开发中,是不会书写_proto_ 属性的
    p1.sayHi();
构造函数、实例、原型对象三者之间的关系.png

解决方法

原型链
原型链.png

原型链查找机制
每当代码读取某个对象的某个属性时,都会执行一次搜索,目标时具有给定名字的属性

1 搜索首先从对象实例本身开始
2 如果在实例中找到链具有给定名字的属性,则返回该属性的值
3 如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性
4 如果在原型对象中找到链这个属性,则返回该属性的值

实例对象读写原型对象成员
值类型成员写入(实例对象,值类型成员 = xx ):

引用类型成员写入(实例对象,引用类型成员 = xx ):

复杂类型成员修改(实例对象,成员 xx = xx )

更简单的原型语法
前面在原型对象每添加一个属性和方法就要书写一遍 Person.prototype。
为减少不必要的输入,更常见的做法是用一个包含所有属性和方法的对象字面量来重写整个原型对象,将 Person.prototype 重置到一个新的对象。
注意:原型对象会丢失 constructor 成员,所以需要手动将 constructor 指向正确的构造函数。

    Person.prototype = {
        constructor : Person, // 需要手动将 constructor 指向正确的构造函数
        type : "human",
        sayName : function(){
            console.log(this,name)
        }
    }

建议
在定义构造函数时,可以根据成员的功能不同,分别进行设置

内置构造函数的原型对象
所有函数都有 prototype 属性对象
Javascript中的内置构造函数也有 prototype 原型对象属性:

继承

封装的构造函数就是用来创建一类对象
继承指的是 类型和类型之间的继承
原型对象可以将自己的属性和方法继承给将来的实例对象使用

函数的 call 方法 6069

call 方法在调用函数的时候,有两个功能
1 更改函数内部的 this执行
2 调用函数执行内部代码
参数:第一个参数用来指定 this,第二个及以后,就是传的实参

构造函数的原型方法继承

student.prototype = new person();
student.prototype.constructor = student;

组合继承
属性在构造函数内部继承,方法通过原型继承

    function person(name,age){
        this.name = name;
        this.age = age;
    }

    person.prototype.sayHi = function(){
        console.log(this.name + ":ni hao");
    }

    function student(name,age,score){
        person.call(this,name,age);
        this.score = score;
    }

    student.prototype = new person();
    student.prototype.constructor = student;

    var s1 = new student("zzj",18,100);
    console.log(s1);
    s1.sayHi();
函数声明和函数表达式
// 函数声明
function fun(){
  console.log(1);
};
// 函数表达式 --- 将函数赋值给一个变量,可以是一个匿名函数
var fn = function (){
  console.log(2);
};

函数声明与函数表达式的区别

函数也是对象

var fn = new Function('var a = "1";console.log(a)');
fun(2)

函数的调用和this 5715

    // 1 普通函数 是通过给函数名或者变量名添加()方式执行
    // 内部的 this 默认指向 window
    function fun(){
        console.log(1);
    }
    fun();
    // 2 构造函数,是通过 new 关键字进行调用
    // 内部的 this 指向的是将来创建的实例对象
    function Person(name){
        this.name = name;
    }
    var p1 = new Person("zs");
    // 3 对象中的方法,是通过对象打点调用函数,然后加小括号
    // 内部的 this 默认指向的是调用的对象自己
    var o = {
        sayHi : function(){
            console.log("hhh")
        }
    }
    o.sayHi();
    // 4 事件函数,不需要加特殊的符号,只要事件被触发,会自动执行函数
    // 事件函数的内部 this 指向的是事件源
    document.onclick = function(){
        console.log("hhh")
    }
    // 5 定时器和延时器中的函数,不需要加特殊符号,只要执行后,在规定的时间自动执行
    // 默认内部的 this 指向的是 window
    setInterval(function(){
        console.log("hhh")
    },1000)

call

    var o = {
        0: 10,
        1: 20,
        2: 30
    };

    Array.prototype.push.call(o,40);



apply

1 功能:第一个可以指定函数的 this,第二个可以执行函数并传参
2 参数:第一个参数,传入一个指定让 this 指向的对象,第二个参数是函数的参数组成的数组
3 返回值:就是函数自己的返回值

    // 定义一组数组,利用 apply 方法,可以将它拆开进行操作
    var arr = [1,3,4,56,8];

    // 想借用一些现在内置在 js 中的方法
    // 利用 apply 方法,将数组传给 max 的第二个参数
    console.log(Math.max.apply(Math,arr))

bind
1 功能:第一个可以指定函数的 this,bind 方法不能执行函数,但是可以传参
2 参数:第一个参数,传入一个指定让 this 指向的对象,第二个参数及以后,是函数参数的列表
3 返回值:返回一个新的指定了 this 的函数,也可以叫绑定函数

    // 想修改的是定时器的函数内部的 this
    var o = {
        name: "zs",
        age: 18,
        s: function(){
            setInterval(
                function(){
                    console.log(this.age);
                }.bind(this),1000);
        }
    }

高阶函数

    // 1 函数作为另一个函数的参数
    // 定义一个函数,吃饭的函数,吃完饭之后,可以做其他的事情,看电影,聊天,看书
    function eat(fn) {
        console.log("吃饭");
        // 接下来的事情不固定
        fn();
    }
    eat(function () {
        console.log("看电影");
    })

    // 2. 函数作为一个函数的返回值
    // 需求:通过同一段代码实现以下效果
    // 输出 100 + m
    // 输出 1000 + m
    // 输出 10000 + m
    function outer(n){
        return function inner(m){
            console.log(m + n);
        }
    }
    // 在外部执行 inner 函数
    // 100 + m
    var fun = outer(100);
    fun(3);
    // 1000 + m
    var fun1 = outer(1000)
    fun(3);
闭包

观察闭包

闭包的用途

上一篇 下一篇

猜你喜欢

热点阅读