美文网首页
javaScript原型与闭包笔记

javaScript原型与闭包笔记

作者: John_Phil | 来源:发表于2019-04-19 17:30 被阅读0次

对象:函数对象与普通对象

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script>
            function fun1(){};
            var fun2 = function(){};
            var fun3 = new Function();//创建匿名函数对象
            
            var obj1 = new fun1();
            var obj2 = {};
            var obj3 =new Object();
            
            
            console.log(Object);     // Object() { [native code] }
            console.log(Function);   // Function() { [native code] }

            console.log(fun1);       // fun1(){}
            console.log(fun2);       // (){}
            console.log(fun3);       // anonymous() {}
            
            console.log(obj1);         // fun1 {}
            console.log(obj2);         // {}
            console.log(obj3);         // {}
            
            console.log(typeof Object);     // function
            console.log(typeof Function);   // function

            console.log(typeof fun1);       // function 函数对象
            console.log(typeof fun2);       // function
            console.log(typeof fun3);       // function 
            
            console.log(typeof obj1);         // object 普通对象
            console.log(typeof obj2);         // object
            console.log(typeof obj3);         // object
            
        </script>
    </head>
    <body>
    </body>
</html>

函数对象与普通对象数据结构

通过以上知道了 对象分类,接着我们来研究一下原型

prototype 与 proto区别:

image.png

1、每一个函数对象都有一个prototype属性,但是普通对象是没有的;prototype下面又有个constructor,指向这个函数。

2、每个对象都有一个名为proto的内部属性,指向它所对应的构造函数的原型对象,原型链基于proto;

我们来看一个例子:
a1,是function所以有prototype
aaa,是object所以有 proto

    function a1(){
                var a=10;
            }
            
       var aaa=new a1();
image.png
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script>
            
            function a1(){
                var a=10;
            }
            
            var aaa=new a1();
            
            //以下方法等价 都是执行a1方法
            console.log(aaa.constructor);
            console.log(a1);
            console.log(aaa.__proto__.constructor);
            
            //以下方法等价 都是 a1的原型
            console.log(a1.prototype);
            console.log(aaa.__proto__);
            
            //原型链
            console.log(aaa.__proto__); //a1的原型
            console.log(aaa.__proto__.__proto__); //object的原型
            console.log(aaa.__proto__.__proto__.__proto__);//null
            
            
        </script>
    </head>
    <body>
    </body>
</html>
原型与原型链

另外通过以上的例子我们发现了原型链的存在


image.png
            //原型链
            console.log(aaa.__proto__); //a1的原型
            console.log(aaa.__proto__.__proto__); //object的原型
            console.log(aaa.__proto__.__proto__.__proto__);//null

根据原型我们来探究一下关系

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script>
            function a1(num){
                this.num=num;
            }
            var aaa=new a1(10);
            var bbb=new a1(20);
            
            console.log(aaa);
            console.log(bbb);
            
            a1.prototype={name:"张三",age:20,hobby:['吃饭','睡觉']};

            var ccc=new a1(30);
            console.log(ccc);
        </script>
    </head>
    <body>
    </body>
</html>
根据prototype创建对象

实例里如果没有对应的变量值,则顺着原型链向上(prototype)查找

                
            function a1(num){
                this.num=num;
            }
            var aaa=new a1(10);
            var bbb=new a1(20);
            
            console.log(aaa);
            console.log(bbb);
        
            a1.prototype={name:"张三",age:20,hobby:['吃饭','睡觉'],num:999};
            
            var ccc=new a1(30);
            console.log(ccc);           
            
            
            //查找顺序 如果实例中有打印出实例中的变量值,如果实例中找不到,则向上查找打印出prototype的变量值
            console.log(ccc.num);
            console.log(a1.prototype.num);
            console.log(ccc.__proto__.num);
            
            console.log(ccc.age);
            
顺着原型链向上查找

区分变量数据来源hasOwnProperty() 方法

            function aaa () {
                
            }
            aaa.prototype.name = "张三";
            var a1 = new aaa();
            a1.sex = "男";
            //sex属性是直接在p1属性中添加,所以是true
            console.log("sex属性是对象本身的:" + a1.hasOwnProperty("sex"));
            // name属性是在原型中添加的,所以是false
            console.log("name属性是对象本身的:" + a1.hasOwnProperty("name"));
            //  age 属性不存在,所以也是false
            console.log("age属性是存在于对象本身:" + a1.hasOwnProperty("age"));
判断是否为同一对象的属性值

proto属性指向1.Object对象的prototype 2.function对象的prototype 3.Object.create(a1)的a1对象

1.Object对象的prototype


image.png
        var a = {};
        console.log(a.__proto__ ===Object.prototype);
image.png

2.function对象的prototype


image.png
            var b=function(){};
            var a=new b();
            console.log(a.__proto__ ===b.prototype);
image.png

3.Object.create(a1)的a1对象


image.png
            var a1 = {};
            var a2 = Object.create(a1);
            console.log(a2.__proto__);
            console.log(a1);
image.png

javascript中的闭包

闭包即内部定义的变量属性,可以突破局部限制,在外部也可以使用。
在java中我们习惯于用内部类来实现闭包。而在javaScript中我们可以通过 来实现闭包。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script>
        var dom = function(){
        var Name = "tom";
        this.Sex = "man";
        this.success = function(){
                console.log("Success");
            };
        };
    
        console.log(dom.Name);//undefined
        console.log(dom.Sex);//undefined
            
        </script>
    </head>
    <body>
    </body>
</html>

外部访问内部变量访问失败

将内部变量作为函数 返回

var person = function(){    
    //变量作用域为函数内部,外部无法访问    
    var name = "tom";       
       
    return {    
           getName : function(){    
               return name;    
           },    
           setName : function(newName){    
               name = newName;    
           }    
        }    
    }();    
    
    console.log(person.getName());    
    person.setName("jerry");    
    console.log(person.getName());   
            
突破作用域实现闭包
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script>
            //javascript 实现闭包的方法 返回对象当中 包含内部元素值
       var dom = function(){
            var Name = "tom";  //私有属性
            this.Sex = "man";
            this.success = function(){
                console.log("Success");
            };
            return{
                name: Name,
                sex:Sex
            }
        }();
    
        console.log(dom)    
        console.log(dom.name);
        console.log(dom.sex);
        
        // 使用原型对象 来实现 闭包
    var dom2 = function(){
            var Name = "tom";  //私有属性
            this.Sex = "man";
            this.success = function(){
                console.log("Success");
            };
            return this;
        };
    console.log(dom2.prototype.constructor());   
    console.log(dom2.prototype.constructor().Sex);
    
    
    //函数降维使用()     数组降维使用[]
   var aaa= function(){
                alert(123);
            }();
  
        
        console.log(dom.Name);
        console.log(dom.Sex);
        console.log(dom);
        </script>
    </head>
    <body>
    </body>
</html>

javascript继承

function Person(){    
    var name = "default";       
       
        return {    
           getName : function(){    
               return name;    
           },    
           setName : function(newName){    
               name = newName;    
           }    
        }    
};   

    var Man = function(){};
    //继承自Person
    Man.prototype = new Person();
    //添加私有方法
    Man.prototype.say = function(){
        console.log("Hello,my sex is man");
    };
    var aaa = new Man();
    aaa.setName("tom");
    aaa.say();
    console.log(aaa.getName());
Man继承Person 使用原型prototype

相关文章

网友评论

      本文标题:javaScript原型与闭包笔记

      本文链接:https://www.haomeiwen.com/subject/kgclwqtx.html