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()

本文转自 ,如有侵权,请联系删除。

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

比如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)

本文转自 ,如有侵权,请联系删除。

我们在创建实例对象是,若忘了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)
    }
}

本文转自 ,如有侵权,请联系删除。

为对象添加原型

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
        }
    }
})()

本文转自 ,如有侵权,请联系删除。