JavaScript基础笔记3 (对象)

对象:

对象类似C语言结构体,{}内是Object的属性,一个属性就是一个键值对(“key: value”),其中键(key)是一个字符串(也叫做属性名),值(value)可以是任何值,包括Object,因此Object可以嵌套。

let user = new Object(); // “构造函数” 的语法
let user = {};  //{}内为空即为空属性字面量
//创建一个对象不一定要有初始属性,可以自由加入和删除属性。

//键是字符串类型,一般不带空格,如果带空格只需要把空格括在引号里:
let user = {
  name: "John",
  age: 30,
  "likes birds": true
};
//调用一个对象的属性可以用".",也可以用[],但是[]内必须是String类型,但是键出了对象之后解释器就不认识了,因此需要将其值用另一个变量存储,或者直接加引号。
let N = "name";
console.log(user[N]);             //John
console.log(user["na"+"me"]);     //John
console.log(user["likes birds"]); //true
console.log(user.N);              //undefined    虽然N和键name都是字符串,但是点还是不能这么用

然后任何Object类型的变量名都可以相互赋值,说白了JavaScript里所有的变量名只是个浮动的指针而已,甚至Object和function之间都能相互赋值:

let you = { age:18, height:114, neko:()=>alert("qwq")  };   //属性里可以有函数
let me = { a:114514, b:1919810, c:"qwq" };
you = me;

you.neko();             //error    you变成me之后,原有的neko属性没了

function add(A,B) { return A+B; }

you = add;
console.log(you(3,4));   //7        you已经成为了function

add = me;
console.log(add.a);     //114514    add已经成为了Object

计算属性:

在花括号字面量中键用[]括起来,可以将[]里变量内容作为键,而不是变量名作为键。

let fruit = prompt("Which fruit to buy?", "apple");

let bag = {
  [fruit]: 5, // 属性名是从 fruit 变量中得到的
};

alert( bag.apple ); // 5 如果 fruit="apple"
//如果输入的不是apple,那就没有这个属性,会弹出undefined

在实际开发中,我们通常用已存在的变量当做属性名。

function makeUser(name, age) {     //通过几个已知的变量生成Object
  return {
    name: name,
    age: age,
  };
}
let user = makeUser("John", 30);
//如果你希望变量名和属性相同,可以将键和值合在一起(属性值简写):

function makeUser(name, age) {
  return {
    name,
    age,
  };
}

除了一个名为__proto__ 的属性,其他所有的变量名都会被当做String处理,不需要担心键名与关键词冲突:

let obj = {     
  for: 1,
  let: 2,
  return: 3,
  0:  0         //即使是数字也会被转成"0"字符串
};
console.log(obj.return);  //3    不会报错,正常使用

in关键词用于计算前者(String)是否在后者(Object)中。

for循环中使用let in结构,可以遍历对象中的所有键,由于key不是关键词,方便用于变量名:

let you = {
	name,
	age:30
};

let a = "name";
console.log(a in you);    //返回Boolean型

for(let key in you) {
	console.log(key,you[key]);   //name           age 30
}
//在遍历时,如果属性为非负整数字符串,那么会优先遍历并排序遍历
//这个非负整数必须严格按只有数字字符组成,空格,正负号,小数点都不能存在

//JavaScript教程给出的例子:想要按数字属性给入的顺序输出,属性名加+号即可,输出时若不想保留+号可以再把字符串转成Number类型
let codes = {
  "+49": "Germany",
  "+41": "Switzerland",
  "+44": "Great Britain",
  // ..,
  "+1": "USA"
};

for (let code in codes) {
  alert( +code ); // 49, 41, 44, 1
}

方法:

作为对象属性的函数被称为方法。定义属性时方法可以简写:

user = {
	sayHi: function() {
        alert("Hello");
	},
};

let user = {
	sayHi() { alert("Hello"); },   //简写,即忽略掉冒号和function
};

let user = {
	sayHi : ()=>alert("Hello");,   //一定程度上也等同于这个
};

与C++中的结构体类似,如果方法需要访问对象内的属性时,可以使用this关键字:

let user = {
    name: "John",
    age: 30,
    sayHi() { alert(this.name); }
};

//如果函数不是某个对象的方法,使用this也不会报错。而当某个对象引入了这个函数作为方法,this的值就会成为引入它的对象
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
  alert( this.name );
}

user.f = sayHi;
admin.f = sayHi;

sayHi();  //          直接调用的话什么都不会输出,但是也不会报错
user.f(); // John  (this == user)
admin.f(); // Admin(this == admin)


//this类型天然是Object,即使函数不是对象的方法
function thistype() {
	alert( typeof this);
}
thistype();    //object

一个易错点:

//this的具体值只会在调用时赋值,若调用时外层为函数,this会赋值为函数的this。

//JavaScript教程的例题:
function makeUser() {
	return {
		name: "John",
		ref: this
	};
}
let user = makeUser();
alert( user.ref.name ); // Error: Cannot read property 'name' of undefined
//ref第一次调用为makeUser函数调用,其值为函数的this(undefined),而不是user的this


//正确代码如下:
function makeUser() {
	return {
		name: "John",
    	ref() {
      		return this;
    	}
  	};
}
let user = makeUser();
alert( user.ref().name ); // John
//这样this在调用时是ref函数的对象,也就是user自己了。
posted @ 2023-07-27 20:16  maple276  阅读(22)  评论(0编辑  收藏  举报