zoukankan      html  css  js  c++  java
  • js 闭包 对象

    为了方便使用,防止污染全局变量,可以把一系列功能封装在一个类中使用

    const CheckObj1 = function(){
        this.checkName = function(){
            console.log("checkName")
        }
        this.checkEmail = function(){
            console.log("checkEmail")
        }
        this.checkPassword = function(){
            console.log("checkPassword")
        }
    }
    

    但上述做法,每次实例化CheckObj时, 实例对象都会复制一份this上的方法, 会产生多余的消耗,可以使用原型链的特性,让所有的实例对象共用一套方法

    这样,所有的实例对象就都会使用原型中的方法而不会单独创建了

    ps:定义在原型上的必须在实例对象中使用

    const CheckObj2 = function(){}
    CheckObj2.prototype.checkName \= function(){
        console.log("checkName")
    }
    CheckObj2.prototype.checkEmail \= function(){
        console.log("checkEmail")
    }
    CheckObj2.prototype.checkPassword \= function(){
        console.log("checkPassword")
    }
    

    可以批量创建原型方法,并且当返回为this时,可实现链式调用

    const CheckObj3 = function(){}
    CheckObj3.prototype \= {
        checkName: function(){
            console.log("checkName")
            return this
        },
        checkEmail: function(){
            console.log("checkEmail")
            return this
        },
        checkPassword: function(){
            console.log("checkPassword")
            return this
        }
    }
    let b \= new CheckObj3()
    b.checkName().checkEmail().checkPassword()
    

    本文转自 https://www.cnblogs.com/xt112233/p/15609779.html,如有侵权,请联系删除。

    闭包的主要作用就是构建一个单独的作用域,里面的一些变量不会污染全局,又可以满足一些必要操作

    比如bookNum,写在外部会污染全局,写在_book里函数中, 静态使用一次又会被销毁, 实例又无法从外部访问

    const Book = (function () {
        // 私有变量
        let bookNum = 0
        // 私有方法
        function checkBook(name) {}
        // 创建类
        function \_book(newId, newName, newPrice) {
            // 私有变量
            let name, price
            // 私有方法
            function checkID(id) {}
            // 特权方法
            this.getName = function () {}
            this.getPrice = function () {}
            this.setName = function () {}
            this.setPrice = function () {}
            // 公有属性
            this.id = newId
            // 公有方法
            this.copy = function () {}
            bookNum ++
            if(bookNum > 100){
                throw new Error("书籍数量超过了100")
            }
            // 构造器
            this.setName(name)
            this.setPrice(price)
        }
        // 构建原型
        \_book.prototype = {
            // 静态公有属性
            isJSBook: true,
            // 静态公有方法
            display: function () {}
        }
    
        return \_book
    })()
    
    const book \= new Book(1, "JS", 100)
    console.log(book)
    

    本文转自 https://www.cnblogs.com/xt112233/p/15609798.html,如有侵权,请联系删除。

    我们在创建实例对象是,若忘了new

    const Book1 = function (title, time, type) {
        this.title = title
        this.time = time
        this.type = type
    }
    const book1 \= Book1("JavaScript", "2021", "js")
    

    在浏览器中,下述执行会依次返回 undefined JavaScript 2021 js

    console.log(book1)
    console.log(this.title)
    console.log(this.time)
    console.log(this.type)
    

    因为没有new创建实例,相当于静态执行了Book1,this指向window, 其实是调用的window.title window.time window.type

    所以可以设计一种安全模式, 防止忘了new

    const Book2 = function (title, time, type) {
        if(this instanceof Book2){
            this.title = title
            this.time = time
            this.type = type
        } else {
            return new Book2(title, time, type)
        }
    }
    

    本文转自 https://www.cnblogs.com/xt112233/p/15609823.html,如有侵权,请联系删除。

    为对象添加原型

    const obj = {
        x:1,
        y:2,
        add:function(a, b){
            return a + b
        }
    }
    

    使用prototype添加原型

    const Empty = function(){}
    Empty.prototype \= obj
    const empty \= new Empty()
    empty.add(1, 2)    // 3
    

    使用Object.create()直接创建继承原型的对象的实例对象

    const test = Object.create(obj, {    // 第二个参数不传默认为{}
        "a": {
            value: 10,
            writable:false
        },
        "b": {
            value: 100
        },
    })
    

    override重载时,不会修改原型本身

    empty.x = 10
    console.log(empty.x)    // 10
    console.log(obj.x)        // 1
    

    查看原型

    Object.getPrototypeOf(empty)
    

    检测属性

    in和hasOwnProperty均可用来检测对象中属性是否存在

    hasOwnProperty只能检测自有属性,无法查找原型链,in可以检测自有属性或继承属性

    const o = {x:1}
    
    o.hasOwnProperty("x")
    "x" in o
    

    getOwnPropertyDescriptor可查看当前属性描述,但只能查看自有属性

    // 输出{ value: 1, writable: true, enumerable: true, configurable: true }
    console.log(Object.getOwnPropertyDescriptor(o, "x"))
    

    为对象添加属性

    数据属性的四个特性分别是:值(value) 可写性(writable) 可枚举性(enumable) 可配置性(configurable)

    Object.defineProperty(o, "y", {
        value: "test",           // 值
        enumerable:false,    // 是否可枚举
        writable:false,         // 可写性
        configurable:false    // 可配置性
    })    
    

    存取器

    存取器属性的四个特性分别是:读取(get) 写入(set) 可枚举性(enumable) 可配置性(configurable)

    const o = {
        x: "",
        get getX(){
            return this.x
        },
        set setX(val){
            this.x = val
        }
    }
    

    可以用闭包来实现私有属性,并定制get set

    const Test = (function(){
        let x \= "10"
        return function(){
            this.getX = function(){
                return x
            }
            this.setX = function(val){
                x \= val
            }
        }
    })()
    

    本文转自 https://www.cnblogs.com/xt112233/p/15613980.html,如有侵权,请联系删除。

  • 相关阅读:
    JVM 综述
    看 Netty 在 Dubbo 中如何应用
    Netty 心跳服务之 IdleStateHandler 源码分析
    Netty 高性能之道
    Netty 解码器抽象父类 ByteToMessageDecoder 源码解析
    Netty 源码剖析之 unSafe.write 方法
    Netty 出站缓冲区 ChannelOutboundBuffer 源码解析(isWritable 属性的重要性)
    Netty 源码剖析之 unSafe.read 方法
    Netty 内存回收之 noCleaner 策略
    Netty 源码阅读的思考------耗时业务到底该如何处理
  • 原文地址:https://www.cnblogs.com/hustshu/p/15614383.html
Copyright © 2011-2022 走看看