js中万物皆对象是个什么概念

283 阅读3分钟

原型、原型链之间的关系

*原型(prototype)  原型链(__proto__)

*所有的函数数据类型天生自带  原型(prototype)属性,而她的属性值就是一个对象,存贮的还是共有的属性和方法。
*每个对象都有一个 原型链(__proto__)属性,而她指向当前实例所属类的原型(prototype),若不确定就是object实例。
*浏览器 ‘默认’ 给原型开辟的堆内存中,有一个constructor,存储的是当前类本身。

面向对象概念:

面向对象、面向过程:
        都是一种编程思想。
js中的面向对象:
        类----实例   每个类都对应一个实例  就像是(人类-->特朗普)
js中的一些内置类:
        数组类Array  数字类Number  对象类Object  日期类Date  正则类RegExp  ... 

js中常见的设计模式:

    *    单例模式:其实就是一个对象,我们把这个对象那个称为 ‘命名空间’
            var per1={
                name:'可爱'
                age:18
                eat:function(){
                    console.log(`${this.name}吃吃吃`)
                }
            }
            var per2={
                name:'可爱2'
                age:22
            }
            var f= per1;
            f();

==========================================

            var tools={   //tools、 utils工具库
                f1:function(){

                },
                f2:function(){

                },
                f3(){

                },
            }
            tools.f1();//这就是说,封装了一个工具库,在用的时候直接调用就可以了
        ========================================================================
    *    高级单例模式:
            var utils=function(){
                var name ='mingtian';
                var sex='man'
                var eat =function(){
                    console.log(`${this.name}吃吃吃`)
                }
                return {
                    name,sex,eat
                }
            }    
            var per3 = utils();//per3任然是个对象,
            console.log(per3.name,per1.name)
            
            per1.name='red'
            per1.eat =functuion(){
                console.log('ear apple')
            }
            per1.eat();
                    //普通单例,是没有私有的内容的。别的人员可以任意更改你的内部属性
            
            per3.name='xiao hong';   
                    //只是修改了per3这个对象中的name属性,并没有改变utils中的name变量
            var per4=utils();
                    //高级单例模式,使用这个单例的人,是改变了不了内部变量的。 
            console.log(per4.name)

        per1的name属性,用的人能否更改?
        per3的name属性,用的人能否更改?
            都是可以更改的,  

====================================

    *    工厂模式:就是一个普通的函数,适用于那些批量生产单例的情况。
            var per1={
                name:'xiaoming';
                eat:function(){
                    console.log(`${this.name}吃饱了`)
                }
                smile(){
                    console.log(`${this.name}开心了`)
                }
            }
            var factory = function(name,eat){
                return{
                    name,
                    eat:function(){ 
                        console.log(`${this.name}吃`)
                     }
                    smile(){  
                        console.log(`${this.name}笑`)
                    }
                }
            }
            var per3=factory('three',111);
                //per1是通过普通单例创造的,而per3就是通过工厂创造的。

==========================================

    *    构造函数模式:这里的函数名约定是大写!(F)。 
             new执行函数的时候,会在变量提升之后,多了一步开辟堆内存,把this指向该堆内存,代码执行完成之后,默认返回this
            
                var F = function(name){
                this.name=name;
                this.eat=function(){    
                    console.log(`${this.eat}吃饱了吗`)
                }
                // return 123 构造函数,若return的是一个值类型,则不影响new的执行结果
                // return []  若返回的是一个引用数据类型,就会覆盖new的执行结果
            }
            var per4=new F('four');
                    //new执行函数的时候,**开辟作用域,形参赋值,变量提升**,然后把函数中的this指向了一个新开辟的堆内存。。然后在这之后,在操作this,其实就是在操作这个堆内存。最后,把this返出来。
            console.log(per4);
 =========  =====   =====   =====   =======   ======  ===========
       构造函数模式和工厂模式之间的区别?
       构造函数模式: 不需要自己创造一个对象 
                     不需要自己主动return内容
       构造函数模式比构造函数模式多了一个原型
       原型是每个函数都有的默认属性,对应的值是一个对象              

=========================================

    *    原型模式:prototype         
            每一个(对象)实例都有一个__proto__的实例,指向所属类的原型;Person.prototype
            每一个(函数)类都有一个prototype的属性,指向自己的原型(prototype)
            每一个类的原型上都有一个constructor属性,指向所有类(函数)本身。
                        
                        var f = function(){
                            console.log(66);
                        }               
                        console.log(f.prototype);
           
        var ary=[];              //字面量的创建方式
        var ary2=new Array();    //通过构造函数模式创建
        ary.push(1,2,3);
        ary2.push(5,6,7);
        console.log(ary,ary2);
        // Array ary2 ary都是Array是的实例
    
        var Person= function(name,age){
            this.name=name;
            this.age=age;
            this.eat=function(){    
                console.log(`${this.eat}吃饱了吗`)
            }
        }
        Person.prototype.play=function(){
            console.log('paly')
                    //在Person类的原型上添加一个play属性,值是一个函数
        }
        var per5=new Person('li',30);
        var per6=new Person('zhu',20);
                //per5 就是Person类的一个实例(就相当于一个对象),Person是一个自定义类
        console.log(per5.paly===per6.paly);//true
        console.log(per5.eat===per6.eat); //false
==    ====    === ====   =====  =====   =====   =====   =======  
  • 作用域链:变量的查找机制,先看变量是不是自己私有的,不是的话就去上级作用域查找
  • 原型链:对象中属性的查找机制,先在自己身上查找,没有的话就通过(原型链)——proto——向自己所属类的原型(prototype)上查找,原型上没有的话,就在通过原型链——proto——向上级原型查找,一直找到基类的原型,有的话就是返回值,没有的话就是undefined。

=========================================

    *    原型:
    function Person(name,age){
        this.name = name;
        this.age=age;
    }
    // 吃喝玩都是属于所有人类的共用属性,把这些共用属性都放到了原型上,(一生只放一次就够了)
    Person.prototype.eat =function(){
        console.log('eat')
    }
    Person.prototype.drink =function(){
        console.log('drink')
    }
    Person.prototype.play =function(){
        console.log('paly')
    }
    var per9 = new Person('lily',119);
    var per0 = new Person('lucky',120);
    per0.paly();
    per9.eat();

    function mypush(ary,...res){
        for(var i =0;i<res.length;i++){
            ary.push(res[i])
        }
    }
    var ary =[1,2,3,4];
    Array.prototype.mypush=function(){
        console.log(this)
        for(var i =0;i<res.length;i++){
            this.push(res[i])
        }
    }
    ary.mypush(4,5,6);
    console.log(ary);