这次彻底理解了Object这个属性

本文详细介绍了JavaScript中对象的创建方式、属性的添加与删除、属性的检查与遍历方法,并深入探讨了属性的分类及其内部特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.实例化Object对象

实例化Object对象的方式有两种:使用Object构造器和使用对象的字面量。例如:

var person1 = {
    name: '李四'
};

var person2 = new Object();
person2.name = '王二';

2.为实列添加属性

我们可以随时随地为对象添加属性,也可以随时修改属性的值。

var person1 = {
    name: '小明'
};

var person2 = new Object();
person2.name = '小红';

//给对象添加属性
person1.age = 23;
person2.age = 25;

//修改属性的值
person1.name = '张三';
console.log(person1.name);      //'张三'
person2.name = '李四';
console.log(person2.name);      //'李四'

3.删除对象中的属性

var person1 = {
    name: '张三'
};

person1.name = null;



console.log(person1.name);      //'张三'

delete person1.name;

console.log(person1.name);      //'undefined'

4.检查属性

由于对象的属性可以被随时随地被修改或删除,因此有时候我们需要检查对象的某个属性是否存在。使用下面的方式检查是不可靠的:

var person1 = {
    name: '张三'
};


person1.name = '';//或者null/undefined

if (person1.name) {

    console.log('存在');

} else {

    console.log('不存在');         //'不存在'
}

使用这种方式可能会得不到正确的结果,如果属性的值是:对象,非空字符串,非零的数或者true,if条件语句会把它们转换成true。如果属性的值是:null,undefined,0,false,NaN,空字符串,if条件语句会把它们转换成false。检差对象中的属性是否存在的更可靠的方式是使用in操作符:

var person1 = {
            name: '张三'
};


person1.name = '';//或者null/undefined

if ('name' in person1) {

    console.log('存在');          //'存在'

} else {

    console.log('不存在');
}

5.遍历实列的属性

默认情况下,我们添加到对象上的属性都是可枚举的,这样的话我们就可以使用for-in循环遍历它们。

var obj = {
    name: '王志龙',
    age: 23,
    gender: '男',
    address: '鹤壁'
};

var propertyName;

for (propertyName in obj){

    console.log('属性名:' + propertyName);
    console.log('属性值:' + obj[propertyName]);
}

for-in循环每循环一次都会将一个属性名赋值给propertyName,直到所有的属性都被遍历一遍为止。

如果我们只是想获取一个对象中的所有属性名,可以使用Object.keys()方法。该方法会以数组的形式返回所有的属性名。

console.log(Object.keys(obj));     // ["name", "age", "gender", "address"]

6.属性的分类

属性的类型分两种:一种是数据属性,一个种是访问器属性。数据属性用来存储一个值,比如所上个例子中的name。访问器属性不包含值,而是定义了一个getset函数,当读取属性时,调用get函数,当写属性时,调用set函数。

下面是一个使用字面量的形式定义访问器属性的语法:

var obj = {

    _myname: 'clw',

    get name(){

        console.log('get方法被调用了');
        return this._myname + '1111';

    },
    set name(value){

        console.log('set方法被调用了');
        this._myname = value;

    }
};

console.log(obj.name);

7.属性的内部

  7.1共享的属性:

数据属性和访问器属性共享的内部特性有两个:一个是[[Enumerable]],这个特性决定了我们是否能够遍历该属性。另一个是[[Configurable]],这个特性决定了我们是否能够改变属性。默认情况下我们在对象上添加的属性都是可枚举、可配置的。

如果我们向改变属性的特性,可以使用Object.defineProperty()方法。该方法接受3个参数:拥有被修改属性的对象、被修改的属性名、包含描述特性的对象。描述符和内部特性名称相同,但是没有方括号。例如,我们将一个属性改成不能枚举,不能配置:

var person1 = {
    name: '张三',
    age: 22
};

console.log(person1.propertyIsEnumerable('name'));

Object.defineProperty(person1, 'name', {
    enumerable: false
});

console.log('name' in person1);                     //true
console.log(person1.propertyIsEnumerable('name'));  //false

var properties = Object.keys(person1);
console.log(properties);                            //["age"]

//delete person1.name;
//console.log(person1.name);                        //'undefined'

Object.defineProperty(person1, 'name', {
    configurable: false
});

delete person1.name;
console.log(person1.name);                          //'张三'

  7.2访问器属性内部的特性:

var obj = {

    _myname: 'clw',

    get name(){

        console.log('get方法被调用了');
        return this._myname + '1111';

    },
    set name(value){

        console.log('set方法被调用了');
        this._myname = value;

    }
};


//上面的代码等价于:

var obj2 = {
    _myname: 'clw'
};


Object.defineProperty(obj, 'name', {
    get: function() {

        console.log('get方法被调用了');
        return this._myname + '1111';

    },
    set: function(value) {

        console.log('set方法被调用了');
        this._myname = value;

    },
    configurable: true,
    enumerable: true
});

  7.3定义多个属性的内部特性:

定义单个属性的内部特性使用Object.defineProperty(),定义多个属性使用的是Object.defineProperties(),这个方法接受2个参数,第一个是属性所属的对象,第二个是包含被定义属性的对象。

  var person1 = {};

        Object.defineProperties(person1, {
            name: {
                value: '张三',
                enumerable: true,
                configurable: true,
                writable: true
            },
            age: {
                value: 23,
                enumerable: false,
                configurable: false,
                writable: false
            },
            address: {
                get: function(){

                },
                set: function(value){

                },
                enumerable: true,
                configurable: true
            }
        });

        console.log(person1.name);              //'张三'
        person1.name = '李四';
        console.log(person1.name);              //'李四'

        console.log(person1.age);               //23
        person1.age = 500;
        console.log(person1.age);               //23

  7.4获取属性内部的特性

获取属性的内部特性的方法有两个:Object.getOwnPropertyDescriptor()Object.getOwnPropertyDescriptors()

var person1 = {};

        Object.defineProperties(person1, {
            name: {
                value: '张三',
                enumerable: true,
                configurable: true,
                writable: true
            },
            age: {
                value: 23,
                enumerable: false,
                configurable: false,
                writable: false
            },
            address: {
                get: function(){

                },
                set: function(value){

                },
                enumerable: true,
                configurable: true
            }
        });

        //获取对象中单个属性的内部特性
        var descriptor = Object.getOwnPropertyDescriptor(person1, 'address');
        //获取对象中所有属性的内部特性
        var descriptors = Object.getOwnPropertyDescriptors(person1);
        console.log(descriptors);

 

转载于:https://www.cnblogs.com/zhoulifeng/p/7523113.html

<think>好的,用户又遇到了一个AttributeError,这次是关于ChromiumOptions的属性设置问题。错误信息显示'retry_times'属性没有setter,说明用户可能仍然在使用错误的API方式来设置这些参数。我需要回顾之前的对话,看看之前的解决方案是否还有遗漏。用户之前已经遇到了两次类似的问题,第一次是关于headless属性的设置方法,第二次是retry_times和timeout的错误调用方式。用户现在尝试将方法调用改为属性赋值,但依然出现错误,提示没有setter。这可能意味着在新版本的DrissionPage中,这些属性可能是只读的,或者需要不同的方法进行设置。 我需要检查DrissionPage的最新文档,确认ChromiumOptions的正确使用方法。可能用户使用的版本中,retry_times、timeout和headless并不是直接可设置的属性,而是需要通过特定的方法或者配置对象来设置。例如,可能这些参数应该通过ChromiumPage的配置方法,或者在创建页面时传递选项参数,而不是直接赋值给ChromiumOptions实例。另外,可能用户混淆了ChromiumOptions和其他配置类,比如WebPage的配置选项。需要确认ChromiumOptions是否真的具有这些属性,或者是否应该使用不同的类来设置这些参数。例如,重试次数和超时时间可能属于页面操作的配置,而不是浏览器选项的一部分。 可能的解决方案包括:查阅DrissionPage的官方文档,确认正确的参数设置方式;使用正确的方法来设置这些参数,例如通过PageConfig或SessionOptions;或者调整代码结构,确保在创建ChromiumPage实例时正确传递配置参数。此外,用户可能需要更新DrissionPage到最新版本,或者检查版本兼容性,因为不同版本的库可能有不同的API设计。如果用户使用的是旧版本,而文档中的方法适用于新版本,升级库可能解决问题。 最后,为了彻底解决用户的困惑,应该提供一个明确的代码示例,展示如何正确设置retry_times、timeout和headless等参数,并解释每个步骤的作用,确保用户理解正确的API使用方法。</think>这是DrissionPage库的API设计变更导致的属性设置错误。以下是基于最新API规范的修正代码: ```python from DrissionPage import ChromiumPage, ChromiumOptions class XHSCrawler: def __init__(self): self.co = ChromiumOptions() self._init_browser() self.page = ChromiumPage(addr_or_opts=self.co) def _init_browser(self): """最新版本的正确配置方式""" # 浏览器参数设置 self.co.set_argument('--no-sandbox') self.co.set_argument('--disable-gpu') # 全局配置设置(正确方法) self.co.set_retry(3) # 设置重试次数 self.co.set_timeout(30) # 设置超时时间 self.co.set_headless(False) # 设置无头模式 # 用户代理设置 self.co.set_user_agent( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' '(KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36' ) # 验证测试 crawler = XHSCrawler() print(f"当前重试次数:{crawler.co.retry_times}") # 输出:3 print(f"当前超时设置:{crawler.co.timeout}") # 输出:30 ``` **关键修正点说明:** 1. **正确API方法**: - 使用`set_retry()`代替直接赋值`retry_times` - 使用`set_timeout()`代替直接赋值`timeout` - 使用`set_headless()`代替直接赋值`headless` 2. **方法参数说明**: ```python self.co.set_retry(times=3) # 设置网络请求重试次数 self.co.set_timeout(seconds=30) # 设置超时时间(单位:秒) self.co.set_headless(False) # 是否启用无头模式 ``` 3. **版本适配建议**: ```python # 检查DrissionPage版本(要求v3.2.15+) import DrissionPage print(DrissionPage.__version__) # 应该 >= 3.2.15 ``` **兼容性处理方案:** ```python # 版本兼容的配置方法 def set_config(co): if hasattr(co, 'set_retry'): co.set_retry(3) else: # 旧版本回退方案 co.retry_times = 3 co.timeout = 30 co.headless = False ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值