2018.09.24 学习笔记 // 前端JavaScript // 原型和原型链

题目:

  • 写一个原型链继承的例子
  • 描述new一个对象的过程
  • zepto(或其他框架源码中如何使用原型链)
  • 如何判断一个对象是数组类型

知识基础:

1. 构造函数:用函数来初始化一个新建对象

    //1.构造函数:用函数来初始化一个新建对象
        //大写字母开头的函数
        function Foo(name,age){
            this.name = name;
            this.age = age;
            this.class = 'class-1';
            //return this; 默认有这一行
        }
        var f = new Foo('beibei',22);

        //乱入:语法糖:某些专门为了程序员开发方便而添加的语法
        var a = {} //var a = new Object()的语法糖
        var a = [] //var a = new Array()的语法糖
        function Foo(){} //var Foo = new Function()的语法糖

        //使用instanceof可以判断一个函数是否是一个变量的构造函数

2. 原型规则与示例

//2.原型规则与示例
        //<1>所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了“null”)    
        var obj = {}; obj.a = 100;
        var arr = []; arr.a = 100;
        function fn(){}
        fn.a = 100;
        
        //<2>所有的引用类型(数组、对象、函数),都有一个__proto__属性(隐式原型),属性值是一个普通的对象
        console.log(obj.__proto__);//{}
        console.log(arr.__proto__);//[]
        console.log(fn.__proto__);//[Function]
        
        //<3>所有的函数,都有一个prototype属性(显式原型),属性值也是一个普通的对象
        console.log(fn.prototype);//fn {}
        
        //<4>所有的引用类型(数组、对象、函数),__proto__属性指向它的构造函数的“prototype”属性值
        console.log(obj.__proto__ === Object.prototype)//true obj的构造函数就是Object
        
        //<5>当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找
        //构造函数
        function Foo(name,age){
            this.name = name;
        }        
        Foo.prototype.alerName = function(){
            alert(this.name)
        } //此时Foo.prototype为 Object{ alerName:function,constructor: function}
        
//创建实例
        var f = new Foo('zhangsan');
        f.printName = function(){
            console.log(this.name);
        }   //此时f为 Foo{name:'zhangsan', printName:function}, 
            //f.__proto__ 为Object{ alerName:function,constructor: function},体现了f.__proto__ === Foo.prototype

        //测试
        f.printName();
        f.alerName();//验证了<5>,这里的this指向f
        f.toString();//要去f.__proto__.__proto___中查找


        //tips:循环对象自身的属性
        var item;
        for(item in f){
            //高级浏览器已经在for in中屏蔽了来自原型的属性
            //但是这里建议大家还是加上这个判断,保证程序的健壮性
            if(f.hasOwnProperty(item)){
                console.log(item);//name printName 没有alertName
                
            };
        };

4. instanceof:用于判断引用类型属于哪个构造函数的方法

f instanceof Foo的判断逻辑是:

  • f的__proto__一层一层往上,能否对应到Foo.prototype
  • 再试着判断 f instanceof Object

问题解答:

5. 如何判断一个对象是数组类型

//如何判断一个变量是数组类型
        var arr = [];
        arr instanceof Array //ture
        typeof arr //object,typeof是无法判断是否是数组的

6. 原型链继承的例子

//理解例子
        function Animal(){
            this.eat = function(){
                console.log('animal eat');
            }
        }
        function Dog(){
            this.bark = function(){
                console.log('dog bark')
            }
        }
        Dog.prototype = new Animal()
        var hashiqi = new Dog()
        
//封装一个DOM查询的例子
        function Elem(id){
            this.elem = document.getElementById(id)
        }
        Elem.prototype.html = function(val){
            var elem = this.elem;
            if(val){
                elem.innerHTML = val
                return this  //链式操作
            }else{
                return elem.innerHTML 
                //innerHTML在js是双向功能:获取对象内容 或 像对象插入内容
            }
        }
        Ele.prototype.on = function(type,fn){
            var elem = this.elem;
            elem.addEventListener(type,fn)
        }

        var div1 = new Elem('div1')
        console.log(div1.html()) //这时val是空 会返回原来页面的内容
        
        div1.html('<p>holle</p>').on('click',function(){
            alert('clicked')
        }).html('<p>javascript</p>') //可以链式操作

7. 描述new一个对象的过程

  1. 创建一个新对象
  2. this指向这个对象
  3. 执行代码,即对this赋值
  4. 返回this

8. zepto(或其他框架源码中如何使用原型链)

  1. 阅读源码是高效提高技能的方式
  2. 但不能“埋头苦钻“有技巧在其中
  3. 慕课网搜索”zepto设计与源码分析“

猜你喜欢

转载自blog.csdn.net/weixin_41004238/article/details/82828436