1.对象
object类型中的直接实例,是一组属性和方法的集合
1)创建方式
1》对象字面量方式
var o={
name:'lisi',
age:20
}
2》构造函数方式
var o=new Object( );
o.name="lisi"; //添加属性
2)访问属性
1》点操作符
o.name //对象名.属性名
2》[ ]
o["name"] //[ ]中是字符串类型的变量名称
o[key]:key变量
3)删除属性
delete o[key]
delete 0.name
4)检测属性
方法一:
in方法:检测当前属性是否为对象的私有/继承属性,如果不是返回false
代码测试:
结果:
方法二:
hasOwnProperty():检测某个属性是否为对象的私有属性
代码测试:
结果:
5.对象序列化
json
JSON.parse():将json字符串类型转换为对象
代码测试:
结果:
JSON.stringify():将对象类型转换为json字符串
代码测试:
结果:
注:先将一个对象用JSON.stringify()转换为字符串之后,再 用JSON.parse()转换回对象后的对象和原来的对象不是一个对象。
测试:
6.构造函数和原型对象
所有函数都有一个原型对象
所有对象都有一个constructor属性
prototype:原型对象
constructor指向构造函数
静态属性/方法:
声明在函数本身内部,只能函数本身调用
1)assign(a,b):将b对象合并到a对象中(合并结果在a中)
两个对象内的属性的属性名不能相同。否则,a里的对应属性值会被b中的覆盖掉。
测试:
2)Object.keys( ):当前对象的所有属性名所构成的数组
测试:
3)Object.values( )当前对象的所有属性值
测试:
4)Object.defineProperty( ) 定义属性
非静态属性/方法:
声明在函数的原型对象中,所有的实例对象均可调用
constructor:构造者
toString( )
valueOf( )
eg:
Object.prototype.constructor
new Object( ).constructor
7.Object.defineProperty(想要定义属性的对象,想要定义的属性名,{对当前属性的一定的描述}) 定义属性
var a={
name:'lisi'
}
a.name=terry;
Object.defineProperty的第三个参数{ }中:
分为两部分:
第一部分:基础属性描述
value:' ' //给当前属性设置属性值
writable: //是否可写,默认false
enumerable: //是否可遍历,默认false
configurable: //是否可配置/删除,默认false
代码测试:
进行删除属性操作delete obj.age后,结果显示age属性并未被删除掉,进行obj.age=30;操作后,结果显示age也没有被修改掉,表明在设置Object.defineProperty时,它的基本属性writable和configurable默认为false,不可写,不可配置/删除。
用for in方法对obj进行遍历,结果显示没有遍历到age,表明在设置Object.defineProperty时,它的基本属性enumerable的默认值为false,默认不可遍历,说明,age属性已经写入obj中了,但由于Object.defineProperty的基本属性的默认设置,目前只是可读,无法对其进行删除,修改,遍历的操作。
通过修改Object.defineProperty的基本属性writable:true,可对obj进行修改,上图显示age修改成功
通过修改Object.defineProperty的基本属性enumerable:true,可对obj进行遍历,上图显示obj遍历成功
通过修改Object.defineProperty的基本属性configurable:true,可对obj进行配置/删除,上图显示age属性删除成功
第二部分:存取操作符
存取操作符在使用的时候不能和value同时使用
set:function //当去设置一个属性的时候调用的函数
get:function //当去获取一个属性的时候调用的函数
测试属性设置顺序:
this._gender=''; //通过隐藏属性(下划线属性)进行设置,this代表调用当前set的一个对象
如果忽略Object.defineProperty(obj,"gender",{}),那么上面是定义一个var obj={ }对象,然后下面直接用obj.gender=‘men’设置gender属性,但在这种情况下,我们不知道究竟是何时设置的gender属性,现在我们就通过Object.defineProperty(obj,"gender",{})自己定义一个gender属性,当obj.gender往里设置值的时候,其实调用的是set:function方法,set:function(v),将‘men’传给v,通过this._gender=v把值设置给gender,当console.log时,直接打印gender,通过调用get:function来获取gender,把设置好的gender,通过return this.gender返回到外面给调用者console.log。
2.函数
已经见过的函数
function say(){ } //自定义函数
Number( ) //转换函数
new Object( ) //构造函数
$ js中,所有函数的内部构造是一致的。函数就是一个对象
普通函数--构造函数
普通函数
构造函数:内部一样,只是调用的时候加了new
如果去声明构造函数时,建议构造函数的首字母大写
1.创建/声明函数
1)函数字面量
var say=function(){ }
2)函数的声明
function say( ){ }
3)匿名函数 //需要立即执行,创建的时候立即执行
function(){ }
(function(){ })( ) //前面的小括号包裹匿名函数,后面的小括号代表调用的意思
代码测试:
-------------------- 直接打印-------------------------
--------------------调用函数--------------------------
------------------将函数的调用放在上面----------------------------
$ js按解析顺序从上到下依次执行,解析顺序为:先解析函数的声明,再解析var操作符声明的变量,但不赋值。
解析顺序为:
2.函数的调用
函数名(参数)
new 函数名( ) //new调用的函数一般为构造函数
3.函数的参数
形式参数(形参)
实际参数(实参)
function say(a,b){ //调用时在函数的括号内给a,b变量,a,b为形参
console.log(a+b);
}
say(1,2); //1,2为实参
形式参数(形参)个数可以和实际参数(实参)个数不一致。
$ js中没有重载概念,只要函数名相同,即为重写
function say(){ }
function say(a){ } //函数名相同,后声明的函数会覆盖先声明的函数
say();
------------函数调用和函数参数代码测试-----------
不设实参:
形参在写上的时候,相当于进行了操作var a;var b;只不过由于没设实参,没有赋值。
设对应形参个数的实参:
设超出形参个数的实参:
不报错,只不过拿不到超出部分的数。
4.函数的内部属性(只能在当前函数内部取用)
arguments:类数组对象 (用来保存实参的)
length:实际参数的个数
callee:从函数内部指向当前函数
测试:
------------直接打印arguments-----------
-------------------设置实参测试---------------------
-------------------测试arguments.length---------------------
-----------------------测试arguments.callee----------------------
结果为当前的sayHello方法
this:
this是函数赖以生存的环境对象
this何时确定:当拥有当前this的函数被调用时确定
this指向谁:谁调用当前拥有this的函数,那么this就指向谁
兜底对象:
html:window
linux/vi:global
****************this测试*******************指向全局window
5.作为值的函数和作为返回值的函数
作为值的函数:如下图
作为返回值的函数:如下图
6.函数的属性
length:返回形式参数个数
调用函数的方法:
//修改函数内部的this值得指向
say.apply(this,[实参列表])
say.call(this,实参列表)
-----------------say.call()测试-----------------
(1)
(2)
(3)
由object变为window对象
--------------------say.apply()测试---------------------