5. 对象

文章详细介绍了JavaScript中创建和操作对象的方法,包括字面量创建、属性的增删改查以及复制。提到了数组的过滤、累加和排序功能,并通过示例展示了如何使用filter、reduce和sort方法。此外,讨论了for...in循环、普通函数与构造函数的区别,以及getter和setter在对象属性访问中的作用。最后,文章演示了如何利用getter和setter实现数据代理。
摘要由CSDN通过智能技术生成

5. 对象

5-1. 字面量创建对象

语法:

var obj = {
name:'atguigu',
age:18
}

属性名:

  1. 属性名可以加引号(单引号、双引号),也可以不加引号

  2. 属性名推荐遵循标识符命名规范

  3. 特殊属性名【不符合标识符命名的属性名】需要加引号

    var obj = {
        "user-info":"atguigu",
        'user-age':19
    }
    
  4. 属性名如果重复,后面会覆盖前面的

    var obj = {
        name:'atguigu',
        age:18,
        name:'尚硅谷' // 最终值
    }
    
    
  5. 操作属性有两种方式:

    5-1. .语法:obj.name

    5-2.【】语法:obj['name']

    注意:. 语法和[]语法的差别,[]语法,可以使用变量.

    var str = 'age';
    var str2 = 'address';
    var obj = {
        [str]:19,
        name:'atguigu',
        address:'宏福科技园'
    }
    console.log(obj[str],obj.name,obj[str2]);
    // 19,atguigu, 宏福科技园
    
  6. 属性的增-删-改-查-复制

    6-1. 增

    var obj = {
        name:'atguigu'
    }
    obj.age = 19
    obj['address'] = '宏福科技园'
    

    6-2. 删

    delete obj['name']
    delete obj.age
    

    6-3. 改

    obj['name'] = '尚硅谷';
    obj.age = 20;
    

    6-4. 查【读属性值】

    console.log(obj.name,obj['age'])
    

    6-5. 复制属性

    var obj1 = {
        name:'atguigu',
        age:19
    }
    var obj2 = {
        ...obj1,// 将obj1中所有的属性都放到obj2中
        address:'宏福科技园'//新增了一个address属性
    }
    // 复制obj1中的属性,但是obj1中的name属性需要修改为 尚硅谷
    var obj3 = {
        ...obj1,
        name:'尚硅谷'
    }
    

    6-6. 属性名 in 对象,检查一个属性是否是obj的属性,是返回true,不是返回false

    注意:in 只能判断是不是属性,无法区分是公有属性还是私有属性。

    var obj = new Object();
    console.log(obj);
    obj.name = 'atguigu';
    obj.age = '男'
    
    var res1 = 'name' in obj;// 检查name是否是obj的一个属性
    console.log('res1: ',res1);//true
    
    var res2 = 'sex' in obj;
    console.log('res2: ',res2);//false
    

5-2. 引用数据类型和基本数据类型区别

基本数据类型是值的操作

引用数据类型是地址的操作

5-3. 数组结合对象

var userList = [
    {
        id:1,
        username:'张三',
        age:15
    },
    {
        id:2,
        username:'李四',
        age:17
    },
    {
        id:3,
        username:'王五',
        age:21
    },
    {
        id:4,
        username:'赵六',
        age:20
    }
];

console.log(userList);
/**
 *  需求一:将年龄超过18岁的同学找到。
 *          filter、forEach
 * 
 *  需求二:计算全班同学的平均年龄.  总年龄 / 人数  reduce
 * 
 *  需求三:将所有同学的按照年龄从大到小排列
 * 
 *  编程式试错的艺术
 * 
 */

// 需求一:将年龄超过18岁的同学找到。
// 方式一:
// var userArr = [];
// userList.forEach(function(user,index){
//     // console.log('user: ', user);// 将user.age > 18 的找到
//     // console.log('index: ', index);
//     if(user.age > 18){
//         userArr.push(user);
//     }
// })
// console.log(userArr);

// 方式二:filter
/**
 *  作用:筛选过滤数组
 *  返回值:筛选后的新数组
 */
var useArr = userList.filter(function(user, index){
    console.log('user: ', user);
    console.log('index: ', index);
    return user.age > 18;
})
console.log(useArr);


//需求二:计算全班同学的平均年龄.  总年龄 / 人数  reduce

// 1. 算出全班同学年龄的总和
var totalAge = userList.reduce(function(pre, cur){
    console.log(pre, cur);
    return pre + cur.age;
},0)

// 2. 算出平均年龄
console.log(totalAge / userList.length);


var sum = 0;
userList.forEach(function(user){
    sum += user.age;
})
console.log(sum/userList.length);

//需求三:将所有同学的按照年龄从大到小排列

/**
 *  sort : 
 *  参数是什么? 回调函数,a b
 *  返回值是什么? 排序后的新数组
 *  改变原数组
 * 
 */

userList.sort(function(a,b){
    // console.log('a: ', a);
    // console.log('b: ', b);
    return b.age - a.age;
})
console.log(userList);

5-4. for…in循环遍历对象

知识点:

  1. for in 循环遍历对象
  2. []语法读取对象属性值
 var obj = {
    name:'atguigu',
    age:19,
    address:'宏福科技园'
}
// attr : attribute [属性]
for(var attr in obj){
    console.log('attr: ', attr);// attr 是遍历时当前次循环的属性名
    console.log('obj: ', obj); // obj 是整个对象
    console.log('obj.attr: ',obj.attr); // obj中的attr属性,是undefined

    console.log('obj[' + attr + ']: ',obj[attr]);
}

5-5. 普通函数和构造函数

普通函数和构造函数的区别:

  1. 调用方式:

    1-1. 普通函数 函数名() 调用

    1-2. 构造函数 new 函数名()

  2. 命名:

    2-1. 普通函数,首字母小写

    2-2. 构造函数,首字母大写

    var arr = new Array(1,3);
    
  3. this指向:

    3-1. 普通函数:调用者是谁,this就指向谁,调用者是谁,就看函数调用的时候前面有没有. ,如果有. ,. 前面的就是调用者,如果没有. ,this就是window

    3-2. 构造函数:this永远指向当前组件实例。

  4. 返回值:

    4-1. 普通函数:返回值需要手动指定, 如果没有return,返回undefined

    4-2. 构造函数:不用写,默认返回 this 当前实例对象

5-5-1. 普通函数创建对象

/**
 *  function 定义函数,有两种
 *  (1) 普通函数:函数名首字母是小写的、普通函数的调用是 函数名()
 *   (2)  构造函数:函数名首字母大写,使用 new 函数名()调用
 * 
 *  判断一个函数是不是构造函数,主要看调用方式,是不是用new关键字调用的
 */

// 用函数也可以创建对象
function createPerson(name,sex){
    console.log('this: ', this);// 普通函数中的this指向其调用者
    // 调用者是谁,取决于函数调用的时候前面有没有. ,如果有就是.前面的。如果没有就是window

    // 1. 创建一个新对象
    var obj = {};
    // 2. 给对象添加属性
    obj.name = name;
    obj.sex = sex;
    // 3. 返回该对象
    return obj;
}

var p1 = createPerson('赵四','man');
console.log(p1);

var p2 = createPerson('王五', 'woman');
console.log(p2);

var obj = {
    fn:createPerson // obj.fn 也指向了 createPerson函数体
}

obj.fn();

5-5-2. 构造函数创建对象

/**
 *  1. 构造函数使用 new关键字调用
 *  2. 构造函数中的this,永远指向当前实例对象
 *  3. 构造函数不用写 return,默认返回当前实例对象[this]
 * 
 */
function Person(name, age){
    console.log('this: ', this);// 构造函数new出来的当前实例对象
    // var obj = {};
    // obj.name = name;
    // obj.age = age;
    // return obj;
    this.name = name;
    this.age = age;
    // return this; // 可以省略
}

var p1 = new Person('赵四', 18);
var p2 = new Person('王五', 29);
console.log('p1: ', p1);
console.log('p2: ', p2);

5-5-3. 构造函数内存结构

function Person(name, age){
    this.name = name;
    this.age = age;
}
var p1 = new Person('张三', 19);
var p2 = new Person('李四', 20);
console.log(p1);
console.log(p2);

5-5-4. 普通函数调用者不同,this指向不同

5-6. in-hasOwnProperty

检测一个属性是否是对象的属性

(1)属性名 in 对象:返回布尔值,无法区分是私有属性还是公有属性。因为只要是属性就返回true

(2)对象.hasOwnProperty(属性):判断一个属性是否是对象的私有属性

function Person(name, age){
    this.name = name;
    this.age = age;
    this.say = function(){
        console.log(this.name, this.age);
    }
}
Person.prototype.eat = function(){
    console.log('eat');
}
Person.prototype.className = '230222';

var p1 = new Person('老张',20);
var p2 = new Person('老李',30);

console.log(p1.name,p1.age,p1.say()); // p1的私有属性
console.log('私有属性: ' , 'name' in p1, 'age' in p1, 'say' in p1);

console.log(p1.eat(), p1.className); // p1 的公有属性
console.log('公有属性: ', 'eat' in p1, 'className' in p1);

// 以上四行console,说明 in 只是检测一个属性或方法是不是对象的属性或方法,不管是公有还是私有。言外之意,in无法区分属性是公有属性还是私有属性

// hasOwnProperty 可以检测一个属性是否是对象的私有属性
console.log('hasOwnProperty: ', p1.hasOwnProperty('name'), p1.hasOwnProperty('age'),p1.hasOwnProperty('say'),p1.hasOwnProperty('className'),p1.hasOwnProperty('eat'), p1.hasOwnProperty('sdfsadklfj'))

/**
 *  需求:自定义一个函数,实现检测变量的公有属性,如果是公有属性返回true ,否则返回false
 * 
 */

function hasPubProperty(obj, attr){
    // 什么是公有属性? 是它的属性,却不是它的私有属性
    return attr in obj && !obj.hasOwnProperty(attr);
}

console.log(hasPubProperty(p1,'name'), hasPubProperty(p1,'eat'), hasPubProperty(p1,'className'));

5-7. getter和setter

语法看上去是函数,但实际使用是属性

getter对应的是读取属性,读取属性的时候,会触发getter的执行,并且getter函数的返回值,就是读取的属性值

setter对应的是设置属性:当给对象的属性赋值时,会触发对应的setter函数执行,并且将=右边设置的值,作为参数传递给setter函数

/**
 *  1. 了解 getter和setter的概念:
 *  2. 了解 getter 和 setter的执行时机
 *      2-1. getter的返回值是什么
 *      2-2. setter的参数是什么
 * 
 * ES6  Object.definedProperty
 * 
 *       getter
 *       setter
 * 
 */

var user = {
    name:'atguigu',
    age:19,
    //getter 函数执行时机:读取name属性的时候执行,并且函数的返回值就是name的属性值
    get name(){
        console.log('获取name的值');
        return 'xxxx'
    },
    // setter 函数执行时机,设置name属性的时候,执行,并且将设置的值传递个参数 val
    set name(val){
        console.log('name 的 setter执行了:',val);
    },
    get age(){
        return 999;
    },
    set age(val){
        console.log('age 的setter', val);
    }
}

user.name = '尚硅谷';

console.log(user.name);

console.log(user.age);
user.age = 1000;
  • getter-setter实现数据代理

    将对变量name值的操作,代理给了user.name属性的操作。

    即,读取user.name 其实读取的是name变量

    设置user.name的值,其实是设置name变量的值

    // 数据代理:
    var name = 'atguigu';
    var user = {
    
        age: 19,
        get name() {
            console.log('获取name的值');
            return name;
        },
        set name(val) {
            console.log('name 的 setter执行了:', val);
            name = val;
        }
    }
    
    // console.log(user.age);
    // console.log(user.name);
    
    // user.age = 29;
    // user.name = '尚硅谷';
    
    console.log(user.name);
    
    user.name = '尚硅谷';
    console.log(user.name);
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值