js基础内容3

基本类型:String、Number、Boolean、

引用类型:对象、函数、数组

特殊:null、undefined

弱数据类型

对象:保存复杂的数据,多个属性、方法的集合

ECMA-262对象的定义:无序属性的集合,其属性可以包含基本值,对象,或者函数。可以将对象想象成散列表:键值对,其中值可以是数据或者函数。ECMAScript中的对象其实就是一组数据(属性)和功能(方法)的集合。

对象是一个包含相关数据和方法的集合(通常由一些变量和函数组成,我们称之为对象里面的属性和方法)

var obj = {

  name:"terry",

  age:12,

  sayName:function(){

    console.log(this.name);

  },

  sayAge:function(){

    console.log(this.age);

  }

}

  1. 对象的创建

创建Object实例

使用构造函数创建,new Object()

var person = new Object();

person.name = "briup";

person.age = 22;  

使用对象字面量表示法

不同的属性之间用','分割,属性名和属性值之间用':'分割

var person = {

     name : "briup",

     age : 22

};

对象的初始化有两种方式,构造函数模式和字面量模式

  1. 字面量模式

对象使用"{}"作为对象的边界,对象是由多个属性组成,属性与属性之间通过","隔开,属性名与属性值通过":"隔开;属性名一般不添加引号(当属性名中出现特殊字符的时候需要添加引号),属性值如果是字符串的一定添加引号。

var obj = {

  name:"terry",

  age:12,

  sayName:function(){

    console.log("my name is ",this.name);

  }

}

  1. 构造函数模式

使用Object或者使用自定义构造函数来初始化对象(例如Student)

var obj = new Object();

obj.name = "terry";

obj.age = 12;

obj.sayName = function(){

  console.log("my name is",this.name);

}

//等价于 <==>

var obj={};

obj.name="terry";

obj.age=12;

2.对象的访问

访问对象属性

点表示法,右侧必须是以属性名称命名的简单标识符

person.name

中括号表示法

中括号中必须是一个计算结果为字符串的表达式,可以通过变量访问属性,如果属性名中含语法错误的字符,或者属性名使用的是关键字或保留字,可以使用中括号

person["first name"]

  1. 属性访问

属性访问方式也有两种,点访问、中括号访问

点后面直接跟的是对象的属性,如果属性存在可以访问到,如果属性不存在,得到undefined。 中括号中放的是变量,中括号可以将该变量进行解析。

obj.name      //'terry'

var name = "name"

obj[name]     //'terry'

name = "age"

obj[name]      //12

  1. 方法的访问

方法的访问主要是为了执行该对象中的方法,需要按照函数调用的方式去使用

//以下执行结果不一样

obj.sayName;

obj.sayName();//方法的使用

  1. 遍历对象中的属性

普通版的for循环可以遍历数组,但无法遍历对象

增强版的for循环:

for..in用于遍历数组或者对象的属性

for(自定义变量名 in 数组/对象){

执行代码

}

for(var key in obj){

var value=obj[key];

}

obj对象:依次从obj中获取到属性名

“自定义变量名key”用来指定是数组的元素索引,也可以是对象的属性

vi  for-in.js

//循环对象属性:

var obj = {

  name:"briup",

  age:12,

  salary:10000

};

/*

两种方式访问属性:

objectName.propertyName

或者

objectName["propertyName"]

*/

console.log(obj.name);

console.log(obj["age"]);

console.log(obj.salary);

for(var key in obj){

  console.log(key+"--"+obj[key]);

}

3.删除对象中的属性

delete只是断开了属性和宿主对象的联系,而不会操作属性中的属性,并且delete只会删除自有属性,不能删除继承属性。在销毁对象时,为了防止内存泄露,遍历对象中的属性,依次删除所有属性。

语法:delete 属性访问表达式

例如:

delete stu.name   //删除学生对象中的name属性  

只能删除对象的自有属性

delete obj.pro

delete obj[“proname”]

delete obj.sayName     //从obj对象中删除sayName属性

4.新增属性并赋值

  Obj.newproname=”value”

5.数据类型转换

Vi object-cast.js

// Object类型到Boolean类型

// 除了空引用(null)会转换为false,其他都被转换为true

var obj = {

name:"briup",

age:12

};

console.log(Boolean(obj));

// Object类型转换为String类型

var obj = {

name:"briup",

age:12,

toString:function(){

return this.name+"--"+this.age;

}

};

    console.log(obj.toString());

console.log(String(obj));

// Object类型转换为Number类型

// valueOf()   toString()

/*

1.如果只重写了valueOf()或者toString()方法,则调用该方法,并将返回值用Number()转换。

2.如果两个方法都重写了,则调用valueOf(),并将返回值用Number()转换。

3.如果两个方法都没有重写,则返回NaN

*/

var obj = {

name:"briup",

age:12,

toString:function(){

return "100";

},

valueOf:function(){

return 10;

}

};

console.log(Number(obj));

6.检测属性

in 检测某属性是否是某对象的自有属性或者是继承属性

Object.prototype.hasOwnProperty()检测给定的属性是否是对象的自有属性,对于继承属性将返回false

Object.prototype.propertyIsEnumerable() 检测给定的属性是否是该对象的自有属性,并且该属性是可枚举的。通常由JS代码创建的属性都是可枚举的,但是可以使用特殊的方法改变可枚举性。

例如:

var o = {

x:1

}

o.hasOwnProperty("x"); //true,x 为o的自有属性

o.hasOwnProperty("y"); //false,o 中不存在属性y

o.hasOwnProperty("toString"); //false,toString为继承属性

o.propertyIsEnumerable(“toString”); //false,不可枚举

 var obj= {

   name: 'zs',

   age: 18,

   school: '大学'  

};

'name' in obj; // true

'grade' in obj; // false

“name” in p1

var b=“first” in p1

//如果用in判断一个属性存在,这个属性不一定是obj的,它可能是obj继承得到的,如:

'toString'  in  obj;  //  true

//因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以obj也拥有toString属性。

//要判断一个属性是否是obj自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法:

obj.hasOwnProperty('name');  //  true

obj.hasOwnProperty('toString');  //  false

7.Object根构造函数的原型

Object构造函数原型对象中的部分属性及方法

Object原型中的所具有的任何属性和方法也同样存在于其他对象中,任何对象继承自Object。Object原型中常用的方法:

constructor  保存用户创建当前对象的函数,与原型对象对应的构造函数

hasOwnProperty(propertyName) 检查给定的属性名是否是对象的自有属性

propertyIsEnumerable(propertyName) 检查给定的属性在当前对象实例中是否存在

valueOf()  返回对象的字符串,数值,布尔值的表示

toLocaleString() 返回对象的字符串表示,该字符串与执行环境的地区对应

toString()  返回对象的字符串表示

isPrototypeOf(object)  检查传入的对象的原型

Object.prototype.isPrototypeOf(obj)  true

a.isPrototypeOf(b)     如果a是b的原型,则返回true。如果b不是对象,或者a不是b的原型,则返回false。

静态方法即构造函数里方法,实例方法即构造函数原型里方法

封装特性:将创建对象的过程封装起来

所有的构造函数都直接或间接继承Object,实例可以访问其构造函数及其父构造函数原型中的方法。Object.prototype中定义了很多公共的属性和方法,可以让所有的实例对象调用。

      1. toSource()

返回字符串表示此对象的源代码形式,可以使用此字符串生成一个新的相同的对象。

      1.  propertyIsEnumerable(prop)

判断某个属性是否是该对象的自有属性,并且该属性是可枚举的。通常由JS代码创建的属性都是可枚举的,但是可以使用特殊的方法改变可枚举性。

vi object.js

var now = new Date();

    console.log(now);

    console.log(now.toString());//Thu Oct 15 2020 21:40:38 GMT+0800 (中国标准时间)

    console.log(now.toLocaleString());//2020/10/15 下午9:40:38

    var obj = new Object();

obj.name = "terry";

obj.age = 12;

obj.gender="male"

//Object根构造函数

//Object.prototype根父类

console.log(obj.toString());

console.log(obj.valueOf());

console.log(obj.hasOwnProperty("name"));

console.log("name" in obj);

console.log(obj.propertyIsEnumerable("name"));

console.log(Object.getOwnPropertyDescriptor(obj,"name"));

console.log(Object,typeof Object);//构造函数

console.log(Object.prototype,typeof Object.prototype);//原型

console.log(Object.prototype.constructor === Object);//构造函数

console.log(obj,typeof obj);//孩子

console.log(obj.__proto__);//父亲-原型,内部属性,不可迭代的属性

console.log(obj.__proto__ === Object.prototype);//true

//constructor是父亲的属性   父亲-孩子:继承

console.log(obj.constructor);//母亲-构造函数

console.log(obj.constructor === Object);//true

Vi useproperty.js

var obj={name:"zs",age:12};

obj.hasOwnProperty("age");//true

obj.hasOwnProperty("gender");//false

obj.hasOwnProperty("constructor");//false

"age" in obj; //true

"gender" in obj;//false

"constructor" in obj;//true

Object.prototype.test=”ttttt”;

obj.hasOwnProperty("test");//false

console.log(obj.test);

//爷爷:Object.prototype  父亲:String.prototype 儿子:str

var str=new String("hello");

console.log(str.test);//ttttt

str.hasOwnProperty("length");//true

str.hasOwnProperty("test");//false

//是否是同一家族的

String.prototype.isPrototypeOf(str);

Object.prototype.isPrototypeOf(str);

String.prototype.isPrototypeOf(obj);

obj instanceof String

str instanceof String

//enumerable:true

for(var i in obj){

console.log(i+"--"+obj[i]);

}

8.深入理解对象-定义属性

ECMAScript中有两种属性:数据属性、访问器属性。这两种属性用于设置属性的高级属性,例如该属性是否可以配置,是否可以读写,是否可以遍历,并且可以通过setter,getter来监听数据的改变。

  1. 数据属性特性

数据属性 例如name属性

包含一个属性值的位置,这个位置可以读取和写入值。数据属性特性如下

[[Configurable]]

表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性(属性直接定义在对象中,默认为true)。 当为false时,不能重新定义不能使用delete删除。

[[Enumerable]]

表示能否通过for-in循环返回属性。(属性直接定义在对象中,默认为true)

[[Writable]] 表示能否修改属性的值。(属性直接定义在对象中,默认为true)

[[Value]] 包含这个属性的数据值 name:jacky

要修改属性默认的特性,必须使用ECMAScript5的Object.defineProperty(属性所在的对象,属性的名字,一个描述符对象)方法

修改属性的默认特性可以使用

Object.defineProperty(obj,property,options) 或者

Object.defineProperties(obj,{

property:options,

property:options,

...

})

Object.defineProperty(obj,'name',{

   configurable:true,

   enumerable:true,

   writable:true,

   value:'terry'

})

console.log(obj.name); 

Object.defineProperty(obj,"name",{enumerable:false})

obj.propertyIsEnumerable("name");//false

注意:当我们创建一个对象并且为对象设置一个属性的时候,该属性默认特性Configurable、Enumerable、Writable默认都为true,value为该属性的值。 

  1. 访问器属性特性

访问器属性 例如:_year--> year(访问器属性)

      访问器属性不包含数据值,包含的是一对get和set方法,在读写访问器属性时,就是通过这两个方法来进行操作处理的。访问器属性不能直接定义,要通过Object.defineProperty()这个Object的静态方法来定义。

访问器属性有如下特性:

[[Configurable]]

表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性(默认为false)。

[[Enumerable]]

表示能否通过for-in循环返回属性(默认为false)。

[[Get]]   在获取属性时调用的函数,默认为undefined

[[Set]]   在写入属性时调用的函数,默认为undefined

使用Object的defineProperty静态方法可以定义对象中的单个数据属性或者访问器属性

var book = { _year :2004,edition:1}

Object.defineProperty(book,"year",{

get:function(){return this._year;},

set:function(year){this._year =year;}

});

Object.defineProperty(book,"_year",{

enumerable:false

});

_year前面的下划线是一种常用的记号,用来表示只能通过对象方法访问的属性。而访问器属性year则包含一个get函数和一个set函数。

访问器属性包含一对setter和getter函数(这两个函数可以缺省),在读取访问其属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter函数并传入新值,这个函数负责决定如何处理数据。定义setter、getter必须通过Object.defineProperty(obj,property,options), 访问器属性可以通过Object.getOwnPropertyDescriptor()查询。

var book = {

  _name:'',   // 内置属性

  age:12

}

Object.defineProperty(book,'name',{

  configurable:true,

  enumerable:true,

  get:function(){

    return this._name;

  },

  set:function(v){

    this._name = "charles "+v

  }

})

console.log(book);

book.name = 'terry';

console.log(book.name)

Vi getset.js

var obj={name:"zs",_age:12}//_age前面的下划线是一种约定,代表属性私有

console.log(obj.name,obj._age,obj.age);//'zs' 12 undefined

//定义的访问器属性Object.defineProperty,在对象是是不存在的属性

Object.defineProperty(obj,"age",{

get:function(){return this._age;},

set:function(newage){

            console.log("生日到了,准备礼物...");

this._age=newage;

if(newage>18) this.name="ww";//想要的一些操作行为

//Object.defineProperty()定义了访问器属性(age),当age属性修改时,name属性和_age属性会相应修改。

}

});

console.log(obj.name,obj._age,obj.age);//'zs' 12 12

obj.age=30;

console.log(obj.name,obj._age,obj.age);//ww 30 30

Object.getOwnPropertyDescriptor(obj,"name");

Object.getOwnPropertyDescriptor(obj,"_age");

Object.getOwnPropertyDescriptor(obj,"age");

//enumerable:true

//name--ww

//_age--30

for(var i in obj){

console.log(i+"--"+obj[i]);

}

//enumerable

Object.defineProperty(obj,"age2",{

get:function(){return this._age;},

set:function(age){this._age=age;},

enumerable: true

});

for(var i in obj){

console.log(i+"--"+obj[i]);

}

//数据的影响:

obj.age=100;

console.log(obj.age,obj._age);

obj._age=200;

console.log(obj.age,obj._age);

由此可以想到数据的双向绑定:

在一个对象(person)中设置一个私有属性(_age:开头下划线代表私有属性),再为这个对象设置访问器属性age(本身还未在对象中定义),当person.age进行修改时触发set函数,通过这个函数可以进行数据的操作,比如数据的判断赋值等一系列操作,从而实现数据的双向绑定。这个原理是vue的本质原理。vue是数据驱动框架,当数据发生改变的时候,视图自动更新。

  1. 定义多个属性

    Object.defineProperties()  Object的静态方法

该方法接受两个对象参数,第一个参数是要添加或者要修改属性的对象,第二个参数是对象的属性和属性的描述  

  var book = {};

  Object.defineProperties(book,{

  _year :{//数据属性

   value:1001},

  edition :{//数据属性

   value:1},

  year :{//访问器属性

    get:function(){

           return this._year+1},

    set:function(year){

           this._year = year}

    }

  });

  console.log(book.year);    

  1. 读取属性的特性

Object.getOwnPropertyDescriptor()

获取指定属性的描述符该方法接受两个参数,第一个为属性所在的对象,第二个为要读取其描述符的属性名称

var descriptor = Object.getOwnPropertyDescriptor(book,"_year");

console.log(descriptor.value);  //1001

console.log(descriptor.configurable) //false  

通过Object.getOwnPropertyDescriptor()可以查询特性

通过Object.defineProperty()可以修改其特性

Object.getOwnPropertyDescriptor(obj,propname)

Object.defineProperty(obj,propname,{});

Object.defineProperties(obj,{pn1:{},pn2:{},pn3:{}});

{configurable:true,enumerable:true,writable:true,value:xxx}

Vi property.js

var obj={name:"zs",age:12};

Object.defineProperty(obj,"name",{configurable:false,enumerable:false,writable:false,value:"lisi"});

Object.getOwnPropertyDescriptor(obj,"name");

Object.getOwnPropertyDescriptor(obj,"age");

//enumerable:true

console.log(obj);

console.log(obj.valueOf());

for(var i in obj){

console.log(i+"--"+obj[i]);

}

//value值已经发生了变化

console.log(obj.name);

obj.age=13;

Object.getOwnPropertyDescriptor(obj,"age");

//writable:true

obj.name="ww";

obj.age=22;

console.log(obj.name,obj.age);//lisi 22

//configurable:true

delete obj.name;//false

delete obj.age;//true

console.log(obj.name,obj.age);//lisi undefined

//多个属性特征一起设置

obj.gender="male";

Object.defineProperty(obj,"gender",{value:"winnie",configurable:true});

Object.getOwnPropertyDescriptor(obj,"gender");

obj.sno=101;

Object.defineProperties(obj,

{

 "gender":{value:"female",writable:false},

 "sno":{enumerable:false}

 }

);

console.log(obj);

Object.getOwnPropertyDescriptor(obj,"gender");

Object.getOwnPropertyDescriptor(obj,"sno");

9.值传递与引用传递(址传递)

基本数据类型的变量:

可以直接操作保存在变量中的实际的值

参数传递的时候传递的是实际值

引用数据类型的变量:

不能直接操作对象的内存空间,实际上是在操作对象的引用。可以为引用类型变量添加属性和方法,也可以改变和删除其属性和方法。

参数传递的时候传递的是引用地址。

var a=10;

var obj1={name:'zs'};

//复制

var b=a;

var obj2=obj1;

console.log(a,b);

b=20;

console.log(a,b);//值传递

console.log(obj1,obj2);

obj2.name='ls';

console.log(obj1,obj2);//引用传递

var obj3={};

for(var k in obj1){

obj3[k] = obj1[k];

}

obj3.name='ww';

console.log(obj1,obj2,obj3);

//值传递:不受影响

//引用传递:受影响, 内存堆中的地址的值

function add(a,b){

a++;

b.age++;

console.log(a,b);

}

var v1=10;

var v2={age:20};

add(v1,v2);

console.log(v1,v2);

10.对象序列化

对象序列化是指将对象的状态转换为字符串,也可以反序列化,将字符串还原为对象函数,RegExp,Error对象,undefined值不能序列化和反序列化。

JSON.stringify(obj) 将对象序列化为Json字符串,只能序列化对象可枚举的自有属性

JSON.parse(jsonStr) 反序列化

将对象转换为字符串的描述,解决对象在io中传递的问题

  1. 常规转换

   obj.toString()

  2. 转换为json字符串

  JSON.stringify(obj)

  3. 转换为查询字符串

  var qs = require('querystring')

  qs.stringify(obj)

vi object-json.js

// 将对象转换为JSON字符串

// {"name":"briup","age":12}

var obj = {

name:"briup",

age:12

};

console.log(obj);  //object类型打印的结果  {name:'briup',age:12}

// 将对象转换为JSON字符串

var json = JSON.stringify(obj);

console.log(json);//string类型的字符串

// 将JSON字符串转换为对象

var json = '{"name":"briup","age":12}';

var obj = JSON.parse(json);

console.log(obj);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值