IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JS面向对象 -> 正文阅读

[JavaScript知识库]JS面向对象

目录

一、构造函数

二、对象成员

2.1、实例成员

2.2、静态成员

三、instanceof

四、constructor

五、原型对象

5.1、原型关系

5.2、原型属性

5.3、原型链

5.4、原型总结

六、对象创建

6.1、对象字面量创建

6.1.1、new构造函数创建

6.1.2、字面量创建

6.1.3、create创建

6.2、工厂模式

6.3、构造函数模式

6.4 构造函数拓展模式

6.5 寄生构造函数模式

6.6、稳妥构造函数模式

6.7、原型模式

6.8、组合模式

6.9、动态组合模式

七、继承

7.1、原型链继承

7.2、构造函数继承

7.3、组合继承

八、Object

8.1、Object自身方法

8.2、Object实例方法

8.2.1、valueOf

8.2.2、toString

8.2.3、toLocaleString

8.2.4、isPrototypeOf

8.2.5、hasOwnProperty

8.2.6、propertyIsEnumerable

8.2.7、getOwnPropertyDescriptor

8.2.8、defineProperty

8.2.9、defineProperties


一、构造函数

ES6 之前, JavaScript 不是基于类来创建,而是基于构造函数( constructor )和原型链(prototype )来创建对象。
构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new关键字一起使用。我们把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
JS 中,使用构造函数时要注意以下两点:
(1) 构造函数用于创建某一类对象,其首字母要大写;
(2) 构造函数要和 new 关键字一起使用才有意义
使用示例:
   <script>
        function Person(name, age) {
            this.name = name;
            this.age = age;
            this.say = function() {
                console.log(this.name + ', ' + this.age);
            };
        }
        var p = new Person('小王', 18);
        p.say();
    </script>
在上面代码中, new 关键字在创建对象时做以下几件事件:
(1)在内存中创建一个新空对象
(2)让 this 指向到这个新空对象
(3)执行构造函数里面的代码,给这个新对象添加属性和方法。
(4) 返回这个新对象

二、对象成员

JavaScript 中,对象成员分为实例成员和静态成员。

2.1、实例成员

实例成员就是构造函数内部通过 this 添加的成员。如上例代码中 name age say 就是实例成员。实例成员只能通过实例化的对象来访问
  <script>
        function Person(name, age) {
            this.name = name;
            this.age = age;
            this.say = function() {
                console.log(this.name + ', ' + this.age);
            };
        }
        var p = new Person('小王', 18);
        console.log(p.name);
        console.log(p.age);
        p.say();
        console.log(Person.name); // Person 
        //Person.say(); // Uncaught TypeError: Person.say is not a function
    </script>

2.2、静态成员

静态成员是在构造函数本身上添加的成员 。如下列代码中 gender 就是静态成员。 静态成员只能 通过构造函数来访问
    <script>
        function Person(name, age) {
            this.name = name;
            this.age = age;
            this.say = function() {
                console.log(this.name + ', ' + this.age);
            };
        }

        var p = new Person('小王', 18);
        console.log(p.name); //小王
        // 添加静态成员 
        Person.gender = '男';
        console.log(p.gender); //undefined
        // 访问静态成员 
        console.log(Person.gender); //男
    </script>

三、instanceof

在面向对象中,可以使用 instanceof 关键字来判断是否为某个对象的实例。
    <script>
        function Dog(name) {
            if (!(this instanceof Dog)) {
                return new Dog(name);
            }
            this.name = name;
        }
        //var dog = new Dog('沙皮狗'); 
        //var dog = Dog('波斯猫'); 
        var dog = Dog('沙皮狗');
        console.log(dog);
    </script>
instanceof 是一个 JavaScript 的关键字,用于判断是否为某个对象的实例,如果是则返回true,否则返回 false

四、constructor

每一个对象在创建时都会自动拥有一个构造函数的属性 constructor
    <script>
        function Person(name) {
            this.name = name;
        }
        var p = new Person('小王');
        console.log(p);
        console.log(p.constructor);
    </script>
注意: constructor 属性是继承自原型对象,指向了构造函数的引用。

五、原型对象

构造函数很方便,但是存在内存空间浪费的问题。而 JavaScript 规定,每一个构造函数都有一个prototype属性,指向另一个对象。注意这个 prototype 就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。
    <script>
        function Person(name) {
            this.name = name;
        }
        Person.prototype.say = function() {
            console.log('hi');
        };
        var p1 = new Person('小王');
        var p2 = new Person('小王');
        console.log(p1.say === p2.say); // true
    </script>

5.1、原型关系

首先来说一下原型对象,实例对象和构造函数三者之间的关系。下面以示例来进行演示讲解
function Foo() {

}
var f1 = new Foo();
说明:
(1) 构造函数:用来初始化新创建对象的函数。上例中的 Foo 就是构造函数。它会自动给 构造函数赋予一个叫 prototype 的属性,该属性指向了实例对象的原型对象。
(2) 实例对象:通过 new 创建的对象就是实例对象,如上例中的 f1 就是实例对象,实例 对象可以创建多个并且是独立的。每一个原型对象中都有一个 __proto__ 对象。每个 实例对象都有一个 constructor 属性,这个属性是继承自父类,它指向了当前的构造 函数。
(3) 原型对象: Foo.prototype
function Foo() {

}
Foo.prototype.name = 'jock';
var f1 = new Foo(); 
console.log(f1.name);

?首先要明确以下几点:

(1) JS 中万物皆对象。方法( Function )是对象,方法的原型 Function.prototype )是对象。因此它们都会具有对象共有的特点。即:对象 具有属性 __proto__ ,可称为隐式原型,一个对象的隐式原型指向构造该对象的 构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方 法。
(2) 方法(Function) 是一个特殊的对象,除了和其他对象一样有上述 __proto__ 属性之外,还有自己特有的属性—— 原型属性( prototype ),这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。原型对象也有一个属性,叫做 constructor ,这个属性包含了一个指针,指回原构造函数。
总结:
(1) 构造函数 Foo() 的原型属性 Foo.prototype 指向了原型对象,在原型对象里有共 有的方法,所有构造函数声明的实例(这里是 f1 f2 )都可以共享这个方法。
(2) 原型对象 Foo.prototype 保存着实例共享的方法,有一个 constructor 指回构造 函数。
(3) 对象 f1 Foo 对象的实例,这个对象有一个 __proto__ 属性,指向构造函数的 原型对象,用于访问原型对象的所有方法。
(4) 原型对象的 __proto__ 指向的是父级对象的原型对象,例如上例中 Foo.prototype.__proto__ 指向是 Object.prototype。

?

5.2、原型属性

本节来说明 prototype 属性的作用。
__proto__ constructor 属性是对象所独有,而 prototype 属性是函数所独有的。 但由于在JS 中函数也是一种对象,因此函数也拥有 __proto__ constructor 属性。
请看下面的示例:
<script>
    function Foo() {}
    Foo.prototype.name = 'jock';
    var f1 = new Foo();
    var f2 = new Foo();
    console.log(f1.name);
    console.log(f2.name);
    Foo.prototype.name = '天子';
    console.log(f1.name);
    console.log(f2.name);
</script>
原型继承的作用:
(1) JS 继承的机制:通过原型对象实现继承。其实我们平时调用的字符串方法、数组方 法、对象方法、函数方法等都是靠 __proto__ 继承而来的。
(2)原型对象的作用就是定义所有实例对象共享的属性和方法。

5.3、原型链

JS 规定, 所有的对象都有自己的原型对象
原型链:对象的原型 => 原型的原型 => 原型的原型的原型。。。。。。 => null
根据原型链查找,如果一层一层往上查找,所有对象的原型最终都可以寻找到 Object.prototype
Object 构造函数的 prototype )。

?

总结:所有的对象都继承了 Object.prototype 上的属性和方法。
示例:
<script>
    function Person(name) {
        this.name = name;
        this.showName = function() {
            console.log('hello');
        };
    }
    Person.prototype.showName = function() {
        console.log(this);
        console.log(this.name);
    };
    Object.prototype.showName = function() {
        console.log('haha');
    };
    var p1 = new Person('张三');
    var p2 = new Person('李四');
    p1.showName();
    p2.showName();
</script>
读取属性和方法的规则:
JS 引擎会先寻找对象本身的属性和方法,如果找不到就到原型对象上去寻找,这样一层一层寻找,直到找到为止,如果找不到就抛出异常。

5.4、原型总结

<script>
    function Foo() {}
    Foo.prototype.name = 'jock';
    var f1 = new Foo();
    // 1. 原型对象和实例对象的关系 
    console.log(Foo.prototype === f1.__proto__);
    // 2. 原型对象和构造函数的关系 
    console.log(Foo.prototype.constructor === Foo);
    // 3. 实例对象和构造函数的关系 
    console.log(f1.constructor === Foo);
</script>

总结一下:

(1)需要牢记两点:①__proto__ constructor 属性是对象所独有的;② prototype 属性是函数所独有的,由于函数也是一种对象,因此函数也拥有 __proto__ constructor属性。

(2)__proto__ 属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的 __proto__ 属性所指向的那个对象(父对象)里找,一直找,直到 __proto__ 属性的终点 null,再往上找就相当于在 null 上取值,会报错。通过__proto__ 属性将对象连接起来的这条链路即我们所谓的原型链。

(3)prototype 属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法,即 f1.__proto__ === Foo.prototype

(4)constructor 属性的含义是指向该对象的构造函数,所有函数最终的构造函数都指向Function。

六、对象创建

JS 中创建对象有以下 9 种方式。

6.1、对象字面量创建

对于对象字面量来创建对象,有以下三种方式

6.1.1、new构造函数创建

<script>
    var obj = new Object();
    obj.name = '张三';
    console.log(obj);
</script>

6.1.2、字面量创建

<script>
    var person = {
        name: '张三',
        age: 18
    }
    console.log(person);
    console.log(person.name);
</script>

6.1.3、create创建

ES5 中定义了另种创建对象的方法:从一个实例对象来生成另一个实例对象。使用Object.create() 方法来创建。
<script>
    var person = {
        name: '张三',
        age: 18,
        say: function() {
            console.log(this.name);
        }
    }
    var p = Object.create(person);
    console.log(p);
    console.log(p.name);
    p.say()
</script>
说明: Object 对象的 create() 方法中的参数 person 作为返回实例对象 p 的原型对象,在person中定义的属性和方法,都能被实例 p 继承下来。

6.2、工厂模式

如果创建单个对象,使用字面量的方式来创建是非常方便快捷的。但是,如果我们要创建很多相似的对象,则使用工厂模式是一个比较好的选择。
<script>
    function createPerson(name, age) {
        var o = new Object();
        o.name = name;
        o.age = age;
        o.say = function() {
            console.log(this.name + ', ' + this.age);
        };
        return o;
    }
    var p1 = createPerson('小王', 20);
    var p2 = createPerson('小刘', 18);
    p1.say();
    p2.say();
    console.log(p1 instanceof Object);
</script>
工厂模式能创建多个类似的对象,但是存在没有解决对象识别的问题。

6.3、构造函数模式

可以通过使用构造函数模式来解决工厂模式中存在的无法解决对象识别的问题。

<script>
    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.showName = function() {
            console.log(this.name);
        };
    }
    var p1 = new Person('邓超', 30);
    var p2 = new Person('孙俪', 29);
    p1.showName();
    p2.showName();
    console.log(p1 instanceof Person);
    console.log(p1 instanceof Object);
</script>
存在问题:使用构造函数模式解决了工厂模式在创建对象是带来的问题,但同时也会产生新问题:在所有实例对象中各自都存有自己的 showName 方法,这样就浪费了资源。

6.4 构造函数拓展模式

构造函数拓展模式解决了构造函数模式中存在的浪费资源的问题。它的设计思想是把方法抽取出来形成一个独立的方法。
<script>
    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.showName = showName;
    }

    function showName() {
        console.log(this.name);
    }
    var p1 = new Person('邓超', 30);
    var p2 = new Person('孙俪', 29);
    p1.showName();
    p2.showName();
    console.log(p1 instanceof Person);
    console.log(p1 instanceof Object);
    console.log(p1.showName === p2.showName);
</script>
构造函数拓展模式解决了系统内存占用的问题,但同时又产生了新的问题:由于函数定义到了对象外部,此时提升为了一个全局函数。是对象中需要有多个方法,是否需要都定义到全局中呢?如果是会污染全局空间,如果不是,那又如何解决?

使用寄生构造函数模式来解决。

6.5 寄生构造函数模式

寄生构造函数模式接合了工厂模式和构造函数模式。

创建一个函数,函数体内实例化一个对象,并且将对象返回,在外部的使用 new 来实例化对象。
<script>
    function Person(name, age) {
        var o = new Object();
        o.name = name;
        o.age = age;
        o.showName = function() {
            console.log(this.name);
        };
        return o;
    }
    var p1 = new Person('邓超', 30);
    var p2 = new Person('孙俪', 29);
    console.log(p1.showName === p2.showName);
    console.log(p1.__proto__ === Person.prototype);
    console.log(p1);
</script>

问题:

(1)还定义相同方法,存在浪费资源

(2)instanceof 运算符和 prototype 属性都没有意义

这种模式要尽量避免。

6.6、稳妥构造函数模式

稳妥构造函数模式是指 没有公共属性,并且它的方法也不引用 this 对象 。设计思想是利用闭包来实现。
<script>
    function Person(name, age) {
        var o = new Object();
        o.name = name;
        o.age = age;
        o.sayName = function() {
            console.log(name);
        };
        return o;
    }
    var p1 = Person('邓超', 30);
    var p2 = Person('孙俪', 29);
    console.log(p1);
</script>

稳妥构造函数其实是接合闭包来构造对象。p1 就是稳妥对象。

这种创建方式也存在如下问题:

(1)浪费内存空间

(2)由于没有使用 new 关键字来创建,所以不能使用 instanceof prototype 属性。

6.7、原型模式

原型模式是使用对象的 prototype 属性来创建对象。

<script>
    function Person() {}
    Person.prototype = {
            constructor: Person,
            name: '天子',
            age: 18,
            sayName: function() {
                console.log(this.name);
            }
        }
        //Person.prototype.constructor = Person.constructor;
    var p1 = new Person();
    console.log(p1.name, p1.age);
    p1.sayName();
    console.log(p1.constructor);
    console.log(p1.constructor === Person);
    var p2 = new Person();
    p2.sayName();
</script>
原型对象模型是使用对象的 prototype 属性来创建对象的公共属性和方法。它有如下缺点:

当某个实例对象修改原型对象中的属性值后,别的实例对象对应的原型对象中的属性值也会被修改。原因在于引用类型值属性会被所有的实例对象共享并且修改,这也是为什么很少使用原型模式的原因。
<script>
    function Person() {}
    Person.prototype = {
        constructor: Person,
        name: '天子',
        age: 18,
        friends: ['王五', '赵六'],
        sayName: function() {
            console.log(this.name);
        }
    }
    var p1 = new Person();
    var p2 = new Person();
    console.log(p1.friends);
    console.log(p2.friends);
    p2.friends.push('孙七');
    console.log(p1.friends);
    console.log(p2.friends);
</script>

6.8、组合模式

组合模式是在原型模式和构造函数模式相接合的一种模式。
<script>
    // 组合模式是原型模式与构造函数模式相接合的一种模式。 
    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.friends = ['孙悟空', '小白龙'];
    }
    Person.prototype = {
        constructor: Person,
        say: function() {
            console.log(this.name + ', ' + this.age + ', ' + this.friends);
        }
    }
    var p1 = new Person('唐僧', 28);
    var p2 = new Person('沙僧', 25);
    p2.friends.push('猪八戒', 23);
    p1.say();
    p2.say();
</script>
注意:改变原型对象的同时,一定要改变该原型对象的 constructor 属性,让它指向当前的构造函数对象 Person

6.9、动态组合模式

动态组合模式是将封装的原型对象封装到构造函数中。
在组合模式中, 如果没有调用 new 关键字来创建实例对象,那么对象的引用会发生改变 —— 指向的不是构造函数对象,而是 Object 对象。原因是没有实例化,为什么要去初始化呢?
<script>
    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.friends = ['孙悟空', '小白龙'];
        if (typeof this.say != 'function') {
            Person.prototype = {
                constructor: Person,
                say: function() {
                    console.log(this.name + ', ' + this.age + ', ' + this.friends);
                }
            }
        }
    }
    console.log(Person.prototype);
    var p1 = new Person('唐僧', 28);
    var p2 = new Person('沙僧', 25);
    p2.friends.push('猪八戒', 23);
    p1.say;
    p2.say;
</script>

七、继承

7.1、原型链继承

在原型对象上所有属性和方法,都能被实例所共享。

   <script>
        function Animal() {
            this.name = 'animal';
        }
        Animal.prototype.getName = function() {
            return this.name;
        };

        function Dog() {}
        // Dog 继承了 Animal 
        Dog.prototype = new Animal();
        // 改变 Dog 构造函数 
        Dog.prototype.constructor = Dog;
        var d = new Dog();

        console.log(d);
        console.log(d.getName());
    </script>
本质:重写原型对象 , 将一个父对象的属性和方法作为一个子对象的原型对象的属性和方法。
通过上面的代码,绘制原型链图如下:

?原型链方式主要存在以下两个问题的:

(1)父类中的实例属性一旦赋值给子类的原型属性,此时这些属性都属于子类的共享属性。

(2)实例化子类型的时候,不能向父类型的构造函数传参。

7.2、构造函数继承

构造函数继承也叫伪类继承或经典继承,即在子类的构造函数内部调用父类的构造函数。

 <script>
        function Animal(name) {
            //this.name = 'animal'; 
            this.name = name;
            this.friends = ['xiaobai', 'xiaohuang'];
        }
        Animal.prototype.getName = function() {
            return this.name;
        };

        function Dog(name) {
            // 构造函数继承 
            //Animal.call(this, name); 
            Animal.apply(this, [name]);
        }
        var d = new Dog('沙皮狗');
        console.log(d.name);
    </script>

7.3、组合继承

组合继承接合了原型链继承和构造函数继承的优点。

    <script>
        function Animal(name) {
            this.name = name;
        }
        Animal.prototype.getName = function() {
            return this.name;
        }

        function Dog(name) {
            Animal.call(this, name);
        }
        // 重写原型对象 
        Dog.prototype = new Animal();
        Dog.prototype.constructor = Dog;
        var d1 = new Dog('沙皮');
        var d2 = new Dog('松狮');
        console.log(d1.name);
    </script>

说明:在组合继承中,重写原型对象,就可以把父类中共享方法继承下来。

八、Object

8.1、Object自身方法

Object对象方法包括本身的方法和实例方法两种。

Object 对象的实例方法就是在 Object 对象的 prototype 原型对象上定义的方法。
下面我们重点来讲 Object 对象本身的方法:

?示例:

    <script>
        var arr = ['a', 'b', 'c'];
        var obj = {
                name: 'e',
                1: 'f',
                2: 'j'
            }
            // Object.keys(对象):参数是一个对象,返回是一个数组 
        console.log(Object.keys(arr)); // 数组的 key 是下标 
        console.log(Object.keys(obj)); // 对象的 key 是属性名 
        console.log('-----------------')
            // Object.getOwnPropertyNames():接收一个对象作为参数,返回一个数组,包含了 该对象自身的所有属性名 
        console.log(Object.getOwnPropertyNames(arr));
        console.log(Object.getOwnPropertyNames(obj));
        console.log('-----------------')

        function Fn() {};
        var f1 = new Fn();
        console.log(Object.getPrototypeOf(f1) === Fn.prototype);
        console.log('-----------------')
            // 空对象的原型是Object.prototype 
        console.log(Object.getPrototypeOf({}) === Object.prototype);
        // Object.prototype 的原型是null 
        console.log(Object.getPrototypeOf(Object.prototype) === null);
        // 函数的原型是Function.prototype 
        function f() {};
        console.log(Object.getPrototypeOf(f) === Function.prototype);
        console.log('-----------------')
            // Object.setPrototypeOf():接收两个参数,第一个参数是现有对象,第二个是原型 对象
        var a = {};
        var b = {
            x: 1
        };
        Object.setPrototypeOf(a, b);
        console.log(a.x);
        console.log(Object.getPrototypeOf(a));

        function F() {
            this.foo = 'foo';
        } // var f = new F();
        var f = Object.setPrototypeOf({}, F.prototype); // 模拟 new 操作 
        F.call(f);
        console.log(f);
        console.log('-----------------')
            // Object.create():接受一个对象作为参数,然后以它为原型,返回一个实例对象 
        var A = {
            hello: function() {
                console.log('hello');
            }
        }
        var B = Object.create(A);
        console.log(Object.getPrototypeOf(B));
        B.hello();
    </script>
说明:
(1) keys() 返回可枚举的属性
(2)getOwnPropertyNames() 返回不可枚举和枚举的属性名都能获取

8.2、Object实例方法

8.2.1、valueOf

Object.prototype.valueOf() 这个方法是返回当前对象的值,默认情况返回对象本身。

    <script>
        var obj = new Object();
        console.log(obj.valueOf());
        console.log(obj.valueOf() === obj); // true,返回对象本身
    </script>

8.2.2、toString

Object.prototype.toString() 方法会返回一个对象的字符串形式,默认返回类型字符串。
    <script>
        var obj2 = {
            a: 1
        };
        // 重写 toString 
        obj2.toString = function() {
            return 'a = 1';
        }
        console.log(obj2.toString());
    </script>

8.2.3、toLocaleString

Object.prototype.toLocaleString() 方法和 Object.prototype.toString() 方法作用一样。
toString() 是国际标准,而 toLocaleString() 是以区域为标准。下面以日期对象为例来进行说明。
    <script>
        var d = new Date();
        console.log(d.toString());
        console.log(d.toLocaleString());
        console.log(d.toLocaleDateString());
        console.log(d.toLocaleTimeString());
    </script>

8.2.4、isPrototypeOf

Object.prototype.isPrototypeOf() 方法是用来判断该对象是否是另一个对象的原型。
    <script>
        var o1 = {};
        var o2 = Object.create(o1); // o1 作为 o2 的原型来创建 o2 对象 
        var o3 = Object.create(o2);
        console.log(o2.isPrototypeOf(o3));
        console.log(o1.isPrototypeOf(o3));
        console.log(o3);
    </script>

8.2.5、hasOwnProperty

Object.prototype.hasOwnProperty() 方法接收一个字符串作为参数,返回一个布尔值。表示该实例对象自身是否具有该属性,继承来的属性返回为false
    <script>
        var obj = {
            a: 123
        }
        console.log(obj.hasOwnProperty('a')); // true 
        console.log(obj.hasOwnProperty('b')); // false,不存在的属性
        console.log(obj.hasOwnProperty('toString')); //false,继承来的属性
    </script>

8.2.6、propertyIsEnumerable

Object.prototype.propertyIsEnumerable() 方法用于判断某个属性是否可以遍历。只能判断实例对象本身的属性,对于继承来的属性和设置不可枚举的属性一律返回false
可枚举即可遍历
    <script>
        var obj = {};
        obj.name = '刘备';
        obj.age = 20;
        console.log(obj);
        console.log(obj.propertyIsEnumerable('name')); // true 
        console.log(obj.propertyIsEnumerable('toString')); // false 
        for (key in obj) {
            console.log(key);
        }
    </script>

8.2.7、getOwnPropertyDescriptor

Object.getOwnPropertyDescriptor() 方法可以获取属性描述对象。它有两个参数:第一个参数是目标对象,第二个参数是目标对象的属性名称。
   <script>
        var arr = [1, 2, 3];
        console.log(Object.getOwnPropertyDescriptor(arr, '0'));
        console.log(Object.getOwnPropertyDescriptor(arr, 'length'));
        console.log(Object.getOwnPropertyDescriptor(arr, 'toString')); //undefined 
        //delete arr[0] 
        //console.log(arr); 
        arr.length = 6;
        console.log(arr);
    </script>
        {
            configurable: false 
            enumerable: false 
            value: 3 
            writable: true
        }

8.2.8、defineProperty

Object.defineProperty() 方法允许我们去改变属性描述对象,如定义或修改一个属性。方法执行后会返回修改后的对象。
Object.defineProperty() 方法有三个参数:第一个参数是属性所在对象,第二个参数是属性名,第三个参数是属性描述对象。
    <script>
        var obj = Object.defineProperty({}, 'name', {
            value: 'lisi',
            writable: true, //可写性 
            enumerable: true, //可遍历
            configurable: true //是否能被删除 
        });
        console.log(obj.name);
        console.log(Object.getOwnPropertyDescriptor(obj, 'name'));
    </script>

8.2.9、defineProperties

Object.defineProperties() 方法的作用和 Object.defineProperty() 方法功能一样,但是它可以对多个属性进行设置。
Object.defineProperties() 方法有两个参数:第一个参数是属性所在对象,第二个参数是属性描述对象。
    <script>
        var obj = Object.defineProperties({}, {
            name: {
                value: 'lisi',
                configurable: true,
                writable: true,
                enumerable: true
            },
            age: {
                value: 18,
                writable: true
            },
            showName: {
                get: function() {
                    return this.name;
                },
                enumerable: true
            }
        })
        console.log(obj);
        console.log(obj.name);
    </script>

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:20:07  更:2022-02-28 15:21:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:35:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码