• JS基础——JavaScript原型和原型链及实际应用


    构造函数

    function Stu(name,age){
    this.name=name;
    this.age=age;
    }
    instanceof 查看引用类型对象是属于哪个构造函数的方法,通过__proto__ 一直往上找prototype,直到找到Object

    原型规则和示例

    所有的引用类型(数组/对象/函数)都可有扩展属性,都有一个隐式原型__proto__属性,所有函数都可以扩展prototype显示原型属性,属性值是个普通的对象,
    所有的引用类型试图得到一个它本身的某个属性,会通过它的隐式原型__proto__去找它构造函数中的prototype
    // 不希望打印出原型的属性,只打印自身属性
    
    for(let item of f){
         if(f.hasOwnProperty(item)){
    console.log(item)
    }
    }
    

      

    原型链

    let f =new Foo();
    f.alertName= function(){
    // 方法具体实现
    }
    f.toString() //toString方法在Foo原型中找,找不到接着要去 f.__proto__.__proto__中查找

    New一个对象的过程

    • 创建一个新的对象
    • this指向这个新的对象
    • 执行代码,即对this赋值
    • 返回this

    原型链继承

    function Elem(id){
      this.elem =document.getElementById(id);
    }
    Elem.prototype.html =function(val){
      if(val){
        return this.elem.innerHTML;
      }
      this.elem.innerHTML= val;
      return this; //将Elem对象返回
    }
    Elem.prototype.on =function(type,func){
      this.elem.addEventListener(type,func);
      return this;
    }
    const elem =new Elem('div1');
    elem.html('张三').on('click',function(){
    console.log('点击了文本,打印张三');
    }).html(‘李四’)

    实际应用

    新建js文件my-z.js,如下是my-z.js文件源码,解释: slice.call能将具有length属性的对象转成数组 document.querySelectorAll(selector) 是个类数组, 没有.slice 原型,所以需要call,

    … 或者[].slice.call(arguments, 0)
    (function(window){
    
        var Z = function(dom,selector) {
            var i,len =dom? dom.length: 0;
            for(i=0;i<dom.length;i++){
                this[i] =dom[i];
            }
            this.length =len;
            this.selector =selector || ''
        }
    
        var zepto = {}
        zepto.Z= function(dom,selector){
            return new Z(dom,selector)
        }
        zepto.init =function(selector){
            var slice = Array.prototype.slice;
            var dom =slice.call(document.querySelectorAll(selector)) //slice.call能将具有length属性的对象转成数组 document.querySelectorAll(selector) 是个类数组, 没有.slice 原型,所以需要call
            return zepto.Z(dom,selector);
        }
        var $=function(selector){
           return zepto.init(selector)
        }
        $.fn = {
            css : function(key,value) {
                alert(key+':'+value);
                return this;
            },
            html : function() {
                return this[0].innerHTML;
            }
        }
        Z.prototype = $.fn;
        window.$=$;
    })(window);

      在index.html 引用该文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>prototype</title>
    <body>
    <div id="div1">div</div>
    <p>title1</p>
    <p>title2</p>
    <p>title3</p>
    <p>title4</p>
    <!--<script type="application/javascript" src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>-->
    <script type="application/javascript" src="my-z.js"></script>
    </head>
    <script type="application/javascript">
        $('#div1').css('font-size','25px').css('color','#1ecc24') //链式调用
        alert($('#div1').html())
    </script>
    </body>
    </html>
    

    JS插件扩展

    为什么要把原型方法放在$.fn?

    1. 只有$会暴露在window 全局变量,暴露多个变量容易造成变量的污染
    2. 将插件扩展到$.fn.xxx这个web api 中,方便使用

    示例如下所示:

    $.fn.extend = function() {
        var options, name, src, copy, copyIsArray, clone,
            target = arguments[0] || {},
            i = 1,
            length = arguments.length,
            deep = false;
        if ( typeof target === "boolean" ) {
            deep = target;
            target = arguments[1] || {};
            i = 2;
        }
        if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
            target = {};
        }
        if ( length === i ) {
            target = this;
            --i;
        }
        for ( ; i < length; i++ ) {
            if ( (options = arguments[ i ]) != null ) {
                for ( name in options ) {
                    src = target[ name ];
                    copy = options[ name ];
                    if ( target === copy ) {
                        continue;
                    }
                    // 当用户想要深度操作时,递归合并
                    // copy是纯对象或者是数组
                    if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                        // 如果是数组
                        if ( copyIsArray ) {
                            // 将copyIsArray重新设置为false,为下次遍历做准备。
                            copyIsArray = false;
                            // 判断被扩展的对象中src是不是数组
                            clone = src && jQuery.isArray(src) ? src : [];
                        } else {
                            // 判断被扩展的对象中src是不是纯对象
                            clone = src && jQuery.isPlainObject(src) ? src : {};
                        }
    
                        // 递归调用extend方法,继续进行深度遍历
                        target[ name ] = jQuery.extend( deep, clone, copy );
    
                        // 如果不需要深度复制,则直接把copy(第i个被扩展对象中被遍历的那个键的值)
                    } else if ( copy !== undefined ) {
                        target[ name ] = copy;
                    }
                }
            }
        }
        // 原对象被改变,因此如果不想改变原对象,target可传入{}
        return target;
    };
    $.fn.highlight = function (options) {
        // 合并默认值和用户设定值:
        var opts = $.fn.extend({}, $.fn.highlight.defaults, options);
        this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
        return this;
    }
    
    // 设定默认值:
    $.fn.highlight.defaults = {
        color: '#d8d030',
        backgroundColor: '#ecfdde'
    }
    

    验证插件效果:

    <script type="application/javascript">
        //验证插件扩展
        $('#div1').highlight({
            color: '#fff',
            backgroundColor: '#333'
        })
    </script>
    

      

     

  • 相关阅读:
    绘制surfaceView 基础类
    globalfifo设备驱动
    Linux设备驱动中的异步通知与异步I/O
    ARM Linux字符设备驱动程序
    s3c2440串口裸板驱动(使用fifo)
    Linux内核结构分析与移植
    带头结点的单链表的初始化,建立,插入,查找,删除
    使用lombok时@Setter @Getter无效
    web 服务中上传文件大小控制
    Flyway 学习时遇到的错误
  • 原文地址:https://www.cnblogs.com/fuGuy/p/9206784.html
Copyright © 2020-2023  润新知