语法:
var obj = { name:'atguigu', age:18 }
属性名:
属性名可以加引号(单引号、双引号),也可以不加引号
属性名推荐遵循标识符命名规范
特殊属性名【不符合标识符命名的属性名】需要加引号
var obj = { "user-info":"atguigu", 'user-age':19 }
属性名如果重复,后面会覆盖前面的
var obj = { name:'atguigu', age:18, name:'尚硅谷' // 最终值 }
操作属性有两种方式:
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-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
基本数据类型是值的操作
引用数据类型是地址的操作
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);
知识点:
- for in 循环遍历对象
- []语法读取对象属性值
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]);
}
普通函数和构造函数的区别:
调用方式:
1-1. 普通函数 函数名() 调用
1-2. 构造函数 new 函数名()
命名:
2-1. 普通函数,首字母小写
2-2. 构造函数,首字母大写
var arr = new Array(1,3);
this指向:
3-1. 普通函数:调用者是谁,this就指向谁,调用者是谁,就看函数调用的时候前面有没有. ,如果有. ,. 前面的就是调用者,如果没有. ,this就是window
3-2. 构造函数:this永远指向当前组件实例。
返回值:
4-1. 普通函数:返回值需要手动指定, 如果没有return,返回undefined
4-2. 构造函数:不用写,默认返回 this 当前实例对象
/**
* 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();
/**
* 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);
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);
检测一个属性是否是对象的属性
(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'));
语法看上去是函数,但实际使用是属性
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);