javascript对象学习--函数不属于任何一个对象

对象对象!!!!

简单基本类型

javascript中的六种主要简单基本类型

  • string

  • number

  • boolean

  • null

  • undefined

  • object

string number boolean null undefined 不是对象,null 有时会被当做一种对象 typeof null 返回 “object”

函数和对象,是特殊的对象,函数是可调用的对象 数组也是对象的一种,数组中内容中内容的组织方式比一般对象复杂

内置对象

  • String

  • Number

  • Boolean

  • Object

  • Function

  • Array

  • Date

  • RegExp

  • Error

他们是Javascript中的一些内置函数,可以当做构造函数调用(new xx)产生一个对应子类型的新对象

1
2
3
var strObject = new String("aaa");
typeof strObject;// "object"
strObject instanceof String //true
1
2
3
var strPrimitive = "aaaaaaa";
typeof strPrimitive// "string"
strPrimitive instanceof String //false

原始值aaaaaaa是字面量,是一个不可变的值,如果要在这个字面量上执行一些操作,需要转换为String对象

在必要时,语言会自动把字符串字面量转换成一个String 对象,

1
2
3
var strPrimitive = "aaaa";
conosle.log(strPrimitive.length);
console.log(strPrimitive.charAt(3));

可以直接在字面量上访问属性和方法因为 引擎自动把字面量转换成String 对象

数值字面量类似

1
42.12.toFixed(2)//引擎会把它转换成new NUmber(42)

Boolean 字面量也是如此

null 和undefined 没有构造形式,只有文字形式,Date只有构造,没有文字形式

Object Array Function RegExp 文字形式和构造形式都是对象,不是字面量

简单比较:

文字形式:简单

构造形式:可以提供一些额外的选项

Error对象,通常在出现异常时自动创建 可以使用 new Error()

内容

注意:对象的内容不是存在对象内部,

在引擎内,对象的内容的值的存储方式是多种多样的,一般不会存在对象容器内部,存在对象内部的是属性名称,他们像指针一样指向指的真正存储位置。

1
2
3
4
5
var myObj = {
a: 2
};
myObj.a //2 属性访问
myObj["a"] //2 键访问

相同: 访问的是同一个位置

不同:

  • 属性访问要求属性满足标识符命名规范
  • 键访问的方式可以接受任意的UTF-8/Unicode字符串 作为属性名
1
2
["super agent"]
["super-agent"]

对象中地属性名是永远是字符串,所以如果使用string 字面量以外的形式访问的话,首先转变成相应的字符串的形式。如下:

[""]语法是使用字符串来访问属性,所以[2] [true] [obj] 相应的变成["2"] ["true"] ["[object Object]"]

可计算属性名

要通过表达式计算属性名 {a+”aa” : “a”}

属性与方法

(函数通常会认为是对象,在其他语言中,对象中地函数通常会称为方法),所以称为方法

从技术角度来讲,函数永远不会属于一个对象

why?

函数与对象的关系最多只能说是间接关系

属性访问返回的是一个函数,它也并不是一个方法。和其他的函数没有任何区别,(除了this的隐式绑定)不属于某个对象。

一个我长久以来的疑问:

1
2
3
4
5
6
7
8
9
10
11
12
function foo () {
console.log("xxx");
}

var someFoo = foo;

var myObj = {
someFoo: foo
};
foo;// f foo () {}
someFoo;//f foo () {}
myObj.someFoo; //f foo () {}

someFoo 和 myObj.someFoo 只是对同一个函数的不同引用,并不能说明这个函数是特别的或者”属于“某个对象的。如果在foo内部定义一个this ,则区别在于 myObj.someFoo 的this会隐式绑定到一个对象

即使在对象的文字形式中声明一个函数表达式,这个函数也不属于这个对象。

他们只是对于相同函数对象的多个引用

1
2
3
4
5
6
var myObj = {
foo: function {}
};
var someFoo = myObj.foo;
someFoo;//function () {}
myObj.foo// function () {}

数组!!!

数组有一套结构化的值存储机制,不限制值的类型

如果为数组添加一个属性,属性名看起来像数字,那么会发生修改而不是添加属性。

​ 复制对象!!!

深复制和浅复制

浅复制:一般类型完全复制,对象类型,复制的是引用

ES6定义的新语法用来实现浅复制;

1
2
3
4
5
6
7
8
9
10
11
12
13
function fn () {

}

var array = [];
var obj = {
a: 2,
b:array,
c: fn
}
//Object.assign(目标对象,源对象1,源对象2,源对象3.....)
var newObj = Object.assign({},obj);
newObj.a === obj.a // true

该方法会遍历源对象的可枚举属性,并将他们复制到目标对象,最后返回目标对象。该方法是用=复制的,所以源对象的一些特性不会复制到目标对象。

属性描述符!!!

1
2
3
4
5
6
7
var obj = {}
Object.defineProperty(obj,"a",function () {
value: 32,
write: true,
configurable: true,
enumberable: true
})

不可写的属性,不可更改,报TypeError错误

1
2
3
4
5
6
7
8
var obj = {}
Object.defineProperty(obj,"a",{
value: 23,
writrable:false
configurable,
enumberable: true
});
obj.a = 123 //TypeError

TypeError表示我们无法修改一个不可写的属性

configurable 不可配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var obj = {}
Object.defineProperty(obj,"a", {
value: 4,
writable: true,
configurable:false,
enumberable: true
});

obj.a = 5//可以修改

Object.defineProperty(obj,"a", {
value: 67,
writable: true,
configurable: true,
enumberable: true
});//TypeError
//不可以修改一个不可配置的属性描述符,将configurable修改成false 是单向操作,不可撤销

有一个例外 你不知道的javascript P113

除了无法修改 configurable还会禁止delete一个configurable的属性

1
2
3
4
5
6
7
var obj = {};
Object.defineProperty(obj,"a",{
.....
configurable: false
});
delete obj.a //
obj.a //....还会有这个属性的值

存在性!!!!

判断一个对象中是真的没有一个属性,还是有这个属性,但是该属性的值是undefine

1
2
3
4
5
6
7
8
var obj = {
a:'2'
};
("a" in obj);//true
("b" in obj);//false

obj.hasOwnProperty("a"); //true
obj.hasOwnProperty("b");//false

in 操作符检查对象,以及该对象的原型链,hasOwnProperty 只会检查属性是否在obj 这个对象中,不会检查原型链。

看起来in 操作符检查的是容器内是否有某个值,但是实际上检查的是某个属性名 是否存在,这对于对象来说非常重要

1
3 in [0,1,3] //false 这个数组李里面的属性名是 0,1,2 没有 3 !!!!!

可枚举性!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj = {b: "2"};
Object.defineProperty(obj,"a",{
value: 2,
enumberable: false
});

("a" in obj) //true
obj.hasOwnProperty("a");//true
for(var i in obj){
console.log(i,obj[i]);
}
obj.propertyIsEnumerable("a"); //false
Object.keys(obj); //只返回可枚举的
Object.getOwnPropertyNames(obj) ;//所有的属性

Object.keys(obj) 返回一个数组,只包含可枚举的属性, Object.getOwnPropertyNames(obj) 返回一个数组,包含所有的可枚举和不可以枚举的属性,两者都是只查找对象直接包含的属性,不会查找原型链。

遍历!!!

for in 循环遍历对象的可枚举属性(包括原型链)for循环遍历和for in循环遍历都是遍历的属性,ES6提供 for of 方法,遍历数组的值。

1
2
3
4
var array = [1,2,3];
for(var i of array) {
console.log(i); //1,2,3
}