Skip to content

javaScript对象

对象类型是一种存储键值对(key-value)的更复杂的数据类型,属性之间用分开

  • key: key值可以是字符串也可以是变量的形式
  • value:value可以是任意类型,包括基本数据类型、函数类型、对象类型等;
  • 方法:方法和函数的区别,函数放在对象里就是方法
  • 注意:当对象当中存在多个相同key的键值对,这样的会根据加载顺序替换前面的key,最后显示的是最后加载替换的key和value

就是 new Object() 的字面量写法 实际上也是使用 new Object() 构造函数创建出来的对象。

注意:每使用 {} (非代码块的形式)一次空的也算都会在内存空间创建对象

// 4.现象四: 引用传递, 但是在函数中创建了一个新对象, 没有对传入对象进行修改
function foo(a) {
//所以这里不是修改了对象的值,而是新建立了一个对象赋值给了a,内存地址也指向了新的地址
a = {
name: "why"
}
}
var obj = {
name: "obj"
}
foo(obj)
console.log(obj)

添加属性的方法 利用的是 foo.name=“zhangsan” 的方法

前面的两种创建对象的方式,一次只能创建一个、

由于多个对象的属性值都相同,使用构造函数创建的方式,可以一次创建多个不同属性的对象,提升代码的复用性

构造函数也称之为构造器(constructor),通常是我们在创建对象时会调用的函数

  • 构造函数也是一个普通的函数,从表现形式来说,和普通的函数没有任何区别;
  • 那么如果这么一个普通的函数被使用new操作符来调用了,那么这个函数就称之为是一个构造函数;
  • 可以说在javaScript中, 被new 操作符来调用的函数就是构造函数
  • 在其他面向的编程语言里面,构造函数是存在于类中的一个方法,称之为构造方法
    • 但是JavaScript中的构造函数有点不太一样,构造函数扮演了其他语言中类的角色
  • 也就是在JavaScript中,类的定义就是构造函数, 将一个构造函数当作一个类的声明
    • 比如系统默认给我们提供的Date就是一个构造函数,也可以看成是一个类;
    • 在ES5之前,我们都是通过function来声明一个构造函数(类)的,之后通过new关键字来对其进行调用;
    • 在ES6之后,JavaScript可以像别的语言一样,通过class来声明一个类;
//第一种 空构造函数
function Person() {}
var obj=new Person()
//之后使用obj.name添加属性和函数和new Object差不多
//第二种
function Bar(name, age) {
//这里this会指向构造函数创建的空对象来添加方法 最后返回这个对象
this.name = name;
this.age = age;
this.fn = ()=> 1+1
}sa
var bar = new Bar();
console.log(bar.name, bar.fn())
  1. new构造函数可以在内存中创建了一个空的对象

  2. 这个构造函数的显式原型 prototype 会赋值到新对象的隐式原型上

  3. this就会指向刚才创建的空对象

  4. 执行构造函数里面的代码给这个空对象添加属性和方法

  5. 如果没有明确的返回一个非空对象,那么this指向的对象会自动返回, 不用写返回值

    new 可以当作一个操作符

3. 构造函数创建对象和字面量对象的区别

Section titled “3. 构造函数创建对象和字面量对象的区别”

对象是一个具体的事物,构造函数则是泛指拥有具体特征的一类,

所以说一个对象是一个类的实例

  • 可以提高代码的复用性,重复的创建对象,只需要提供不同的属性值,打印时有具体的类型
  • 字面量的和new Object() 的方式 在打印对象的时候类型都是Object,构造函数创建的对象在打印的时候是自己的类型

函数extend于Object, 函数本身也是一个对象类型 , 也是放在堆内存当中,他的类型function当用typeof得到一个函数对象的类型时,它仍然会返回字符串 “function”, 这个本来是返回Object的但是js规范是返回function, 但是本质上就是一个object

//构造函数写法
var bar = new Function();
console.log(typeof bar);
//字面量写法
function bar() {}
  • 注意一点的是这里的 对象实例.name打印的是类名
//定静态方法
function Foo() {}
//函数是本质是一个对象可以给对象添加方法
//这个是类方法也叫静态方法 就像Array.form()
Foo.age = 123;
console.log(Foo2.age);
//output 123

一句话概括 就是和java中创建对象 定义变量都是一样的,方法则是 没有 public void

  • 默认没有显示定义的话,就会默认添加有空构造函数,和toString()。toValue,

  • 可以定义get,set,但是弱类型语言的话也是加不加也每什么用直接就能获取属性和方法

  • 可以使用 static 关键字

  • 有私有属性和私有方法的区分,有这个提案是用#,添加在变量的前面,外部调用会报错

    如果这样的话get和set方法就有作用了

    • 现有的解决方案 :是用Symbol
  • 添加/修改:

    • obj.newVariable="新的属性的值"
    • obj[“newVariable”] = ”新的属性指“
  • 删除:delete obj.newVariable

  • 获取对象属性

    1. obj.newVariable,这种相对简单一点,所有常用

    2. 同样不能使用 - 来链接属性

    3. ES6obj["newVariable"],ES6 允许字面量定义对象时,(表达式)作为对象的属性名,即把表达式放在方括号内。

      印象中应该是叫计算属性是es6的语法

      1. 方括号内必须是字符串,如果输入的是其他类型也会转换为字符串

      方括号运行我们在定义或者操作属性时更加的灵活;

      可以用来读取中间存在空格 . 数字开头 特殊符号 的key值,也可以使用这种方式直接调用函数,中括号内一定要是字符串,对象属性则无所谓

    var obj={
    //这样的写法式主流
    name: "zhangsan",
    //使用计算属性 es6的语法
    ["zhangsan" + "s"]: "wangwu",
    //也可以是字符串
    "age s": "17"
    "fn": function(){
    console.log("first")
    }
    };
    console.log(obj["fn"]())
    console.log(obj1['a' + 'ge s'])//也可以使用表达式的方法
    //output 17
    console.log(obj.zhangsans)
    //output wangwu

for ... in是为遍历对象属性而构建的(函数也会遍历),数组也可以使用但是key值就是索引了,所以不建议与数组一起使用,数组可以用Array.prototype.forEach()for ... of

枚举属性:可以修改的属性

迭代的key值都是String类型

  • 会遍历当前对象中和对象的**显示原型链 (要注意是原型链中的所有枚举类型的)**属性和方法 的key
//可以直接返key值,数组对象的返回索引值
for (var key in info) {
var value = info[key]
console.log(`key: ${key}, value: ${value}`)
}

可迭代对象(包括 ArrayMapSetStringTypedArrayarguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

  • 但是不能迭代对象类型,因为对像类型不是可迭代对象
var foo=[
{name: "张三"},
{name: "张三"},
{name: "张三"},
{name: "张三"}
]
//temp可以直接获取数组元素的值
for(let temp of foo){
console.log(temp)
}
/*output
{ name: '张三' }
{ name: '张三' }
{ name: '张三' }
{ name: '张三' }
*/

注意:JavaScript中没有堆栈的概念,通过堆栈的方式,可以让大家更容易理解代码的一些执行方式

程序是需要加载到内存中来执行的,我们可以将内存划分为两个区域:栈内存和堆内存

1、栈(操作系统)︰由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;

2、堆(操作系统):存储复杂类型(对象)指向的内存空间,一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。

  • 原始类型,和 引用类型的16进制的0x…地址值 会在栈开辟一个空间,占据的空间是在栈内存中分配的;
    1. 原始类型也被称之为值类型;
    2. 在变量中保存的是值本身
    3. 变量中保存的是对象的“引用”
  • 对象类型会在堆中开辟一个空间,占据的空间是在堆内存中分配的;
    • 对象类型也被称之为引用类型
    • 真正保存对象的地方是在堆内存中,栈中保存的是对象类型的引用(对象的地址值)

简单描述:就是谁调用,this就指向谁 windows调用就执行windows,java 中 this是执行当前对象

  • 函数的默认执行: 函数的默认调用就是,自行调用(独立调用),无论在那段代码里面自行调用this就是windows

JavaScript中的函数不仅可以通过上面的方法进行调用,还可以使用new关键字来调用函数,当使用new来调用的函数,一般称为构造函数(ES6中的类),以这样的方式来调用的函数this所绑定的值,就叫做new绑定。

Object.is(value1, value2): 用来判断两个对象是否相等,NaN也会判断

Object.keys(obj): 返回所有key值的数组

Object.values(obj):返回所有value 的数组

Object.create(): 使用指定的原型对象和属性创建一个新对象。

const person = {
isHuman: false,
printIntroduction: function() {
console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}
};
const me = Object.create(person);
me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

Reflect.ownKeys(obj)

Reflect.ownKeys返回一个数组,包含对象自身的(不含继承的)所有键名,**不管键名是 Symbol 或字符串,也不管是否可枚举。**都会返回

Object.assign()方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象。

  • 注意: 由于undefinednull无法转成对象,所以如果它们作为参数,就会报错。

如果 非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefinednull不在首参数,就不会报错

  • 所用:用于给对象添加属性方法
  • 合并对象
  • 变量查找是根据作用域链一层一层的向上查找,最后回到window对象上面查找找不到就会返回undefinde;
  • var 定义的全局变量,和function函数都会会默认添加到window对象上面
  • 浏览器将将一些全局的函数/变量/对象,放到window对象上给我们使用