学js的第二十一天

1.面向对象

  • 在js中,有2种编程思维

    • 面向过程:

    • 面向对象:

  • 核心就是对象(类),对象的组成有2种 {"name":ls, skill:function(){console.log("敲代码")} }

    • 属性:描述 静态的

    • 方法:行为 动态的

  • 面向对象三大特点

    • 封装

    • 继承

    • 多态

1.1==创建面向对象==

1.1.1字面量创建

==缺点:创建单个==

     var obj = {
            "name": "zs",
            "age": 23,
            "skill": function () {
                console.log("敲代码")
            }
        }
        console.log(obj);
        console.log(obj.age);//23
        obj.skill(); //敲代码
      
    </script>

1.1.2new关键字创建

==缺点:代码冗余==

 <script>
        // 创建张三的对象
        // 1.创建空对象
        var obj = new Object();
        console.log(obj);//{}
        // 2.添加属性和方法
        obj.name = "李四";
        obj.age = 20;
        obj.skill = function(){
            console.log("敲代码")
        }
        console.log(obj);
        obj.skill();
    </script>

1.1.3工厂模式创建

==缺点:类别识别不明确,代码冗余 浪费内存==

    <script>
        function createObj(name,age){ // name 张三 age 20
            //1.创建空对象
            var obj =   new Object();
            //2.添加属性和方法
            obj.name = name;
            obj.age = age;
            obj.skill = function(){
                console.log("敲代码")
            }
            // 3.出厂  设置返回值
            return obj;
        }
       var res1 = createObj("张三",20);
       console.log(res1);
       var res2 = createObj("李四",20);
       console.log(res2);
    </script>

1.1.4构造函数创建

==缺点:浪费内存==

==如何创建构造函数==

  • 构造函数的函数名首字母必须大写,为了和普通函数做区别

  • 方法和属性是直接给this

  • 必须使用new关键字进行调用 否则和普通函数没有区别

==new操作符做了什么==

  1. 隐式创建了一个空对象,让this指向这个空对象

  2. 执行构造函数中的代码

  3. 将实例化对象的__ proto __ 指向构造函数的prototype

  4. 隐式返回对象

 <script>
        // 创建构造函数
        function Person(name, age) {
            //new关键字 隐式创建了一个空对象 让this指向这个空对象
            //添加属性和方法  必须加给this
            this.name = name,
            this.age = age,
            this.skill = function () {
                    console.log("敲代码")
                }
            // new关键字 隐式返回这个对象
        }
​
        // 实例化对象(调用构造函数)  必须使用new关键字
        var res1 = new Person("张三", 20);
        console.log(res1);
          var res2 = new Person("李四",10);
        
    </script>

1.1.5原型创建

==缺点:不能传参==

//创造构造函数
        function Person(){}
        // 将方法和属性添加到构造函数的prototype上 共享的属性和方法
        console.dir(Person);
        Person.prototype.name  = "张三";
        Person.prototype.age = 20;
        Person.prototype.skill = function(){
            console.log("敲代码")
        }
        console.dir(Person);
​
        // 实例化对象 
        var res1 =  new Person();
        console.log(res1);//实例化对象的__proto__指向构造函数的prototype
        console.log(res1.__proto__);
​
        var res2 = new Person();
        console.log(res2);
        console.log(res2.__proto__);

1.1.6混合创建

构造函数创建(传参)+原型创建(不传参)

 <script>
        /* name age传参  skill不传参 */
        // 创建Student构造函数
        function Student(name, age) {
            this.name = name
            this.age = age
        }
        // 原型创建   prototype
        Student.prototype.skill = function () {
            console.log("学习敲代码")
        }
​
        // 实例化对象 
        var res1 = new Student("张三", 20);
        console.log(res1);
​
        var res2 = new Student("李四", 15);
        console.log(res2);
​
        console.log(res1.name);//张三
        res.skill();//学习敲代码
        res.skill1();// 
    </script>

1.2==什么是原型和原型链==

  • 原型prototype:构造函数中用来存储共享的方法和属性的对象

  • 原型属性 __ proto __ :让实例化对象的 proto__指向构造函数的prototype

        // Array是js内部创建好的构造函数
        console.dir(Array);
        // 实例化对象  实例化对象的__proto__指向构造函数的prototype
        var arr = new Array(1,2,3,4,5);
        console.log(arr);
        console.log(Array.prototype === arr.__proto__);//true
​
        console.dir(Array.prototype);//Array上共享的属性和方法
​
​
        var arr = new Array(1,2,3,4,5); //arr的__proto__ 指向Array的prototype
            
        var arr1 = new Array(4,5,6,6);// arr1的__proto__指向Array的prototype
  • 原型链:在创建构造函数和实例化对象的时候 自动形成一种查找关系

    先查找自身的属性和方法 然后再找proto,再找构造函数 如果都找不到返回undefined

1.3==this的指向==

1.this的指向问题

  • 在事件处理函数中 this指向当前触发事件的对象(标签)

  • 在Object数据类型中的方法中 this指向所在方法的对象

  • 在普通函数中 this指向window

  • 在构造函数中 this指向实例化对象

<script>
        // 1.在事件处理函数中  this指向当前触发事件的对象(标签)
        var btn1 = document.getElementById("btn1");
        btn1.onclick = function(){
            console.log(this);//
        }
        // 2.在Object数据类型中的方法中  this指向所在方法的对象
        var obj = {
            "name":"zs",
            "eat":function(){
                console.log(this);//obj
            }
        }
        obj.eat();
​
​
        // 3.在普通函数中  this指向window
        function fun1(){
            console.log(this);//window
        }
        fun1();
​
        // 4.在构造函数中  this指向实例化对象
        function Person(name){
            this.name = name,
            this.skill = function(){
                console.log(this);//实例化对象
            }
        }
        var res =  new Person("ls");
        res.skill();
    </script>

2.如何改变this指向

  • call(this的新指向,参数1,参数2......) 参数是分开写的 用逗号分隔

  • apply(this的新指向,[参数1,参数2.....])

  var obj = {
            "name": "小红",
            "age": 10,
            "getName": function () {
                console.log(this.name);
            }
        }
        obj.getName();// 小红  this指向 obj
​
        var obj1 = {
            "name": "小明"
        }
        obj.getName.call(obj1);//this指向obj1  小明
​
        function fun1() {
            console.log(this)
        }
        fun1();//this指向window
        fun1.call(document.documentElement);
        fun1.call(1);//
        fun1.call("123");//
​
​
        function fun2(a, b) {
            console.log(a, b, this);
        }
        fun2(100, 200);// 100 200 window
        fun2.call(obj1, 100, 200);// 100 200 obj1:{name:"小明"}
​
        // 详细检测数据类型   
        console.log(Object.prototype.toString.call("124"))
        console.log(Object.prototype.toString.call(123))
        console.log(Object.prototype.toString.call(true))
        console.log(Object.prototype.toString.call(undefined))
        console.log(Object.prototype.toString.call(null))
        console.log(Object.prototype.toString.call({}))
        console.log(Object.prototype.toString.call([]))
        console.log(Object.prototype.toString.call(function () { }))
        console.log(Object.prototype.toString.call(new Date()))
        console.log(Object.prototype.toString.call(/\d/gi))
                
                //instanceof 检测当前数据是否属于某个构造函数
        function Person() {
            this.name = "ls"
        }
        var res = new Person();
        // 检测res是否由Person构造函数创建的
        console.log(res instanceof Person);//true 
        // apply(this的新指向,[参数1,参数2......])
        function fun3(a,b){
            console.log(this,a,b)
        }
        fun3();//window
        fun3.apply(obj1,[100,200]);// obj1 100 200
        
                //利用Math.max和Math.min求数组中最大的值和最小的值
        var arr = [100,80,120,60];
        //  Math.max(序列1,序列2.....)
        var a =  Math.max.apply("12344",arr);
        console.log(a);
        var a = Math.min.apply("123",arr);
        console.log(a);

2.面向对象的选项卡

    <script>
        // var btn = document.getElementsByTagName("button");
        // var odiv = document.getElementsByTagName("div");
        // for(var i = 0;i<btn.length;i++){
        //     btn[i].index =i;
        //     btn[i].onclick = function(){
        //         for(var j = 0;j<odiv.length;j++){
        //             odiv[j].style.display = "none";
        //         }
        //         odiv[this.index].style.display = "block";
        //     }
        // }
        /*
            面向对象的选项卡
                创建面向对象构造函数   面向对象都是由属性和方法组成的
                标签作为对象的属性    点击事件和for循环作为对象的方法
        */
​
        function SwitchTab() {
            // 添加属性
            this.btn = document.getElementsByTagName("button");
            this.odiv = document.getElementsByTagName("div");
            var that = this;// 在这里this还是指向实例化对象的
            // 入口方法 添加方法
            this.init = function () {
                for (var i = 0; i < this.btn.length; i++) {
                    this.btn[i].index = i;
                    this.btn[i].onclick = function () {
                        // console.log(this);//在事件处理函数中 this指向当前触发事件的对象
                        // 如何让this指向实例化对象
                        that.changeItem(this.index);//想让this指向实例化对象
                    }
                }
            }
            // 入口方法调用
            this.init();
            this.changeItem = function (index) {
                for (var j = 0; j < this.odiv.length; j++) {
                    this.odiv[j].style.display = "none";
                }
                // this.index  想让this指向触发对象  但是现在这个this指向实例化对象
                this.odiv[index].style.display = "block";
            }
        }
        // 实例化对象
        new SwitchTab();
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值