主题
JavaScript 对象
作用域
变量是编程中的基本组成部分。我们声明变量来存储不同的数据类型。要声明变量,我们使用关键字 var
、let
和 const
。变量可以在不同的作用域中声明。在本节中,我们将了解变量的作用域,以及使用 var 或 let 时变量的作用域。
变量作用域可以是:
- 全局作用域
- 局部作用域
变量可以在全局或局部作用域中声明。我们将看到全局和局部作用域。 任何不使用 let、var 或 const 声明的变量都在全局级别作用域。
窗口全局对象
不使用 console.log() 打开浏览器并检查,如果你在浏览器中写 a 或 b,你会看到 a 和 b 的值。这意味着 a 和 b 已经在窗口中可用。
js
//scope.js
a = 'JavaScript' // 不使用 let 或 const 声明变量会使其在窗口对象中可用,并且可以在任何地方找到
b = 10 // 这是一个全局作用域变量,在窗口对象中找到
function letsLearnScope() {
console.log(a, b)
if (true) {
console.log(a, b)
}
}
console.log(a, b) // 可访问
全局作用域
全局声明的变量可以在同一文件的任何地方访问。但是全局这个术语是相对的。它可以是文件的全局,也可以是相对于某些代码块的全局。
js
//scope.js
let a = 'JavaScript' // 是全局作用域,在此文件的任何地方都能找到
let b = 10 // 是全局作用域,在此文件的任何地方都能找到
function letsLearnScope() {
console.log(a, b) // JavaScript 10,可访问
if (true) {
let a = 'Python'
let b = 100
console.log(a, b) // Python 100
}
console.log(a, b)
}
letsLearnScope()
console.log(a, b) // JavaScript 10,可访问
局部作用域
声明为局部的变量只能在某个代码块中访问。
- 块作用域
- 函数作用域
js
//scope.js
let a = 'JavaScript' // 是全局作用域,在此文件的任何地方都能找到
let b = 10 // 是全局作用域,在此文件的任何地方都能找到
// 函数作用域
function letsLearnScope() {
console.log(a, b) // JavaScript 10,可访问
let value = false
// 块作用域
if (true) {
// 我们可以从函数内部和函数外部访问
// 但在 if 内部声明的变量不能在 if 块外部访问
let a = 'Python'
let b = 20
let c = 30
let d = 40
value = !value
console.log(a, b, c, value) // Python 20 30 true
}
// 我们不能访问 c,因为 c 的作用域只在 if 块内
console.log(a, b, value) // JavaScript 10 true
}
letsLearnScope()
console.log(a, b) // JavaScript 10,可访问
现在,你对作用域有了理解。用 var
声明的变量只作用于函数,但用 let
或 const
声明的变量是块作用域(函数块、if 块、循环块等)。JavaScript 中的块是两个大括号 ({}) 之间的代码。
js
//scope.js
function letsLearnScope() {
var gravity = 9.81
console.log(gravity)
}
// console.log(gravity), Uncaught ReferenceError: gravity is not defined
if (true){
var gravity = 9.81
console.log(gravity) // 9.81
}
console.log(gravity) // 9.81
for(var i = 0; i < 3; i++){
console.log(i) // 0, 1, 2
}
console.log(i) // 3
在 ES6 及以上版本中有 let
和 const
,所以你不会受到 var
的狡猾之苦。当我们使用 let
时,我们的变量是块作用域的,它不会影响代码的其他部分。
js
//scope.js
function letsLearnScope() {
// 你可以使用 let 或 const,但 gravity 是常量,我更喜欢使用 const
const gravity = 9.81
console.log(gravity)
}
// console.log(gravity), Uncaught ReferenceError: gravity is not defined
if (true){
const gravity = 9.81
console.log(gravity) // 9.81
}
// console.log(gravity), Uncaught ReferenceError: gravity is not defined
for(let i = 0; i < 3; i++){
console.log(i) // 0, 1, 2
}
// console.log(i), Uncaught ReferenceError: i is not defined
let
和 const
的作用域是相同的。区别只在于重新赋值。我们不能更改或重新赋值 const
变量的值。我强烈建议你使用 let
和 const
,通过使用 let
和 const
,你将编写干净的代码并避免难以调试的错误。作为经验法则,你可以对任何会改变的值使用 let
,对任何常量值使用 const
,对于数组、对象、箭头函数和函数表达式也是如此。
对象
一切都可以是对象,对象有属性,属性有值,所以对象是键值对。键的顺序不是保留的,或者没有顺序。 要创建对象字面量,我们使用两个大括号。
创建空对象
空对象:
js
const person = {}
创建带值的对象
现在,person 对象有 firstName、lastName、age、location、skills 和 isMarried 属性。属性或键的值可以是字符串、数字、布尔值、对象、null、undefined 或函数。
让我们看一些对象的例子。对象中的每个键都有一个值。
js
const rectangle = {
length: 20,
width: 20
}
console.log(rectangle) // {length: 20, width: 20}
const person = {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
age: 250,
country: 'Finland',
city: 'Helsinki',
skills: [
'HTML',
'CSS',
'JavaScript',
'React',
'Node',
'MongoDB',
'Python',
'D3.js'
],
isMarried: true
}
console.log(person)
从对象获取值
我们可以使用两种方法访问对象的值:
- 使用 . 后跟键名(如果键名是一个单词)
- 使用方括号和引号
js
const person = {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
age: 250,
country: 'Finland',
city: 'Helsinki',
skills: [
'HTML',
'CSS',
'JavaScript',
'React',
'Node',
'MongoDB',
'Python',
'D3.js'
],
getFullName: function() {
return `${this.firstName}${this.lastName}`
},
'phone number': '+3584545454545'
}
// 使用 . 访问值
console.log(person.firstName)
console.log(person.lastName)
console.log(person.age)
console.log(person.location) // undefined
// 可以使用方括号和键名访问值
console.log(person['firstName'])
console.log(person['lastName'])
console.log(person['age'])
console.log(person['age'])
console.log(person['location']) // undefined
// 例如,要访问电话号码,我们只使用方括号方法
console.log(person['phone number'])
创建对象方法
现在,person 对象有 getFullName 属性。getFullName 是 person 对象内部的函数,我们称之为对象方法。this
关键字指的是对象本身。我们可以使用 this
来访问对象的不同属性的值。我们不能使用箭头函数作为对象方法,因为在箭头函数内部,this
指的是窗口而不是对象本身。对象示例:
js
const person = {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
age: 250,
country: 'Finland',
city: 'Helsinki',
skills: [
'HTML',
'CSS',
'JavaScript',
'React',
'Node',
'MongoDB',
'Python',
'D3.js'
],
getFullName: function() {
return `${this.firstName} ${this.lastName}`
}
}
console.log(person.getFullName())
// Asabeneh Yetayeh
为对象设置新键
对象是可变的数据结构,我们可以在对象创建后修改对象的内容。
在对象中设置新键:
js
const person = {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
age: 250,
country: 'Finland',
city: 'Helsinki',
skills: [
'HTML',
'CSS',
'JavaScript',
'React',
'Node',
'MongoDB',
'Python',
'D3.js'
],
getFullName: function() {
return `${this.firstName} ${this.lastName}`
}
}
person.nationality = 'Ethiopian'
person.country = 'Finland'
person.title = 'teacher'
person.skills.push('Meteor')
person.skills.push('SasS')
person.isMarried = true
person.getPersonInfo = function() {
let skillsWithoutLastSkill = this.skills
.splice(0, this.skills.length - 1)
.join(', ')
let lastSkill = this.skills.splice(this.skills.length - 1)[0]
let skills = `${skillsWithoutLastSkill}, and ${lastSkill}`
let fullName = this.getFullName()
let statement = `${fullName} is a ${this.title}.\nHe lives in ${this.country}.\nHe teaches ${skills}.`
return statement
}
console.log(person)
console.log(person.getPersonInfo())
sh
Asabeneh Yetayeh is a teacher.
He lives in Finland.
He teaches HTML, CSS, JavaScript, React, Node, MongoDB, Python, D3.js, Meteor, and SasS.
对象方法
有不同的方法来操作对象。让我们看看一些可用的方法。
Object.assign
:复制对象而不修改原始对象
js
const person = {
firstName: 'Asabeneh',
age: 250,
country: 'Finland',
city:'Helsinki',
skills: ['HTML', 'CSS', 'JS'],
title: 'teacher',
address: {
street: 'Heitamienkatu 16',
pobox: 2002,
city: 'Helsinki'
},
getPersonInfo: function() {
return `I am ${this.firstName} and I live in ${this.city}, ${this.country}. I am ${this.age}.`
}
}
//对象方法:Object.assign, Object.keys, Object.values, Object.entries
//hasOwnProperty
const copyPerson = Object.assign({}, person)
console.log(copyPerson)
使用 Object.keys() 获取对象键
Object.keys
:将对象的键或属性作为数组获取
js
const keys = Object.keys(copyPerson)
console.log(keys) //['firstName', 'age', 'country','city', 'skills','title', 'address', 'getPersonInfo']
const address = Object.keys(copyPerson.address)
console.log(address) //['street', 'pobox', 'city']
使用 Object.values() 获取对象值
Object.values
:将对象的值作为数组获取
js
const values = Object.values(copyPerson)
console.log(values)
使用 Object.entries() 获取对象键和值
Object.entries
:在数组中获取键和值
js
const entries = Object.entries(copyPerson)
console.log(entries)
使用 hasOwnProperty() 检查属性
hasOwnProperty
:检查对象中是否存在特定的键或属性
js
console.log(copyPerson.hasOwnProperty('name'))
console.log(copyPerson.hasOwnProperty('score'))
🌕 你太棒了。现在,你拥有了对象的强大力量。你刚刚完成了第8天的挑战,你在通往伟大的道路上前进了8步。现在为你的大脑和肌肉做一些练习。
💻 练习
练习:级别 1
- 创建一个名为 dog 的空对象
- 在控制台上打印 dog 对象
- 为 dog 对象添加 name、legs、color、age 和 bark 属性。bark 属性是一个返回 woof woof 的方法
- 从 dog 对象获取 name、legs、color、age 和 bark 值
- 为 dog 对象设置新属性:breed、getDogInfo
练习:级别 2
在 users 对象中找到拥有最多技能的人。
从以下对象中计算已登录用户,计算积分大于等于50的用户。
jsconst users = { Alex: { email: 'alex@alex.com', skills: ['HTML', 'CSS', 'JavaScript'], age: 20, isLoggedIn: false, points: 30 }, Asab: { email: 'asab@asab.com', skills: ['HTML', 'CSS', 'JavaScript', 'Redux', 'MongoDB', 'Express', 'React', 'Node'], age: 25, isLoggedIn: false, points: 50 }, Brook: { email: 'daniel@daniel.com', skills: ['HTML', 'CSS', 'JavaScript', 'React', 'Redux'], age: 30, isLoggedIn: true, points: 50 }, Daniel: { email: 'daniel@alex.com', skills: ['HTML', 'CSS', 'JavaScript', 'Python'], age: 20, isLoggedIn: false, points: 40 }, John: { email: 'john@john.com', skills: ['HTML', 'CSS', 'JavaScript', 'React', 'Redux', 'Node.js'], age: 20, isLoggedIn: true, points: 50 }, Thomas: { email: 'thomas@thomas.com', skills: ['HTML', 'CSS', 'JavaScript', 'React'], age: 20, isLoggedIn: false, points: 40 }, Paul: { email: 'paul@paul.com', skills: ['HTML', 'CSS', 'JavaScript', 'MongoDB', 'Express', 'React', 'Node'], age: 20, isLoggedIn: false, points: 40 } }
从 users 对象中找到 MERN 栈开发者
在不修改原始 users 对象的情况下,在 users 对象中设置你的名字
获取 users 对象的所有键或属性
获取 users 对象的所有值
使用 countries 对象打印国家名称、首都、人口和语言。
练习:级别 3
创建一个名为
personAccount
的对象字面量。它有firstName, lastName, incomes, expenses
属性,并且有totalIncome, totalExpense, accountInfo, addIncome, addExpense
和accountBalance
方法。Incomes 是一组收入及其描述,expenses 是一组支出及其描述。**** 问题:2、3 和 4 基于以下两个数组:users 和 products
js
const users = [
{
_id: 'ab12ex',
username: 'Alex',
email: 'alex@alex.com',
password: '123123',
createdAt:'08/01/2020 9:00 AM',
isLoggedIn: false
},
{
_id: 'fg12cy',
username: 'Asab',
email: 'asab@asab.com',
password: '123456',
createdAt:'08/01/2020 9:30 AM',
isLoggedIn: true
},
{
_id: 'zwf8md',
username: 'Brook',
email: 'brook@brook.com',
password: '123111',
createdAt:'08/01/2020 9:45 AM',
isLoggedIn: true
},
{
_id: 'eefamr',
username: 'Martha',
email: 'martha@martha.com',
password: '123222',
createdAt:'08/01/2020 9:50 AM',
isLoggedIn: false
},
{
_id: 'ghderc',
username: 'Thomas',
email: 'thomas@thomas.com',
password: '123333',
createdAt:'08/01/2020 10:00 AM',
isLoggedIn: false
}
];
const products = [
{
_id: 'eedfcf',
name: 'mobile phone',
description: 'Huawei Honor',
price: 200,
ratings: [
{ userId: 'fg12cy', rate: 5 },
{ userId: 'zwf8md', rate: 4.5 }
],
likes: []
},
{
_id: 'aegfal',
name: 'Laptop',
description: 'MacPro: System Darwin',
price: 2500,
ratings: [],
likes: ['fg12cy']
},
{
_id: 'hedfcg',
name: 'TV',
description: 'Smart TV:Procaster',
price: 400,
ratings: [{ userId: 'fg12cy', rate: 5 }],
likes: ['fg12cy']
}
]
想象你从 MongoDB 数据库获取上述用户集合。 a. 创建一个名为 signUp 的函数,允许用户添加到集合中。如果用户存在,告知用户他已经有一个账户。
b. 创建一个名为 signIn 的函数,允许用户登录应用程序
products 数组有三个元素,每个元素都有六个属性。 a. 创建一个名为 rateProduct 的函数来评价产品 b. 创建一个名为 averageRating 的函数来计算产品的平均评分
创建一个名为 likeProduct 的函数。这个函数将帮助喜欢产品(如果它没有被喜欢)并移除喜欢(如果它被喜欢了)。
🎉 恭喜!🎉