js对象的总结(1)

一、对象的定义:

                对象是JavaScript的一个基本数据类型,是一种复合值,它将很多值(原始值或者其他对象)聚合在一起,可通过名字访问这些值。即属性的无序集合。

二、对象的创建(3种方法)

1、对象直接量/字面量:

var obj = {
                name: 'zsn',
                age: 18
            }
            console.log(obj.name);//zsn

 

2、构造函数:

  1. 系统自带的, ps: new Object(), Array(), Number(), Boolean(), Date()...
var obj = new Object();
            obj.name = 'zsn';
            console.log(obj.name);
//            zsn

       2.自定义的: 为了和普通函数区分,首字母大写,采用大驼峰写法;

function Obj(name){
    this.name = name;
    this.age = 18
}
var obj = new Obj('zsn');
console.log(obj.name);//zsn
console.log(obj.age);//18

自定义构造函数的基本构造原理:

        关键是有没有new这个操作符,不用new,Obj('zsn')就是一个函数的正常执行,没有返回值,则默认返回undefined;

而是用new操作符后js引擎就会将该函数看作构造函数看待,返回值就是一个对象了。demo如下:

function Obj(){
                this.age = 18;
            }
            //不用new
            console.log(Obj());//undefined
            //用new
            console.log(new Obj());//Obj {age: 18}

用new和不用new不同的原因:

不用new,函数内的this指向的是window,所以this.xxx定义的变量都是window上的属性,但为什么使用new后其中的this就不是window对象了呢?那是因为用new后,js引擎会在函数被进行两步隐士操作(假设构造函数名为Person):第一步, var this = Object.create(Peson.prototype);   (也是创建对象的一种方法,下边会讲到)  隐士的改变函数内this的含义,现在函数内的this是一个原型为Person.prototype, 构造函数为Person的对象(其实此过程就将想要的对象基本创造成功了,只是差些属性而已,从此可是看出构造函数创建对象的最根本原理是借用Object.create()方法来实现的,只不过被封装功能化了); 第二步, 在创建的对象设置完所需要的属性后,隐士的将创建的对象this通过return返回  return this; 

        通过代码的展现:

//  构造函数的原型
          

 Person.prototype = {
                say: function(){
                    console.log('I am saying');
                }
            }
            //  构造函数
            function Person(){
                 //  隐士操作
                 //var this = Object.create(Person.prototype);
                 
                 //返回对象属性的设置
                 this.name = "zsn";
                 this.age = 18
                 
                 //  隐士操作
                 //return this;
            }
            var person1 = new Person();
            console.log(person1.name); //zsn
            person1.say(); //I am saying

上述两步理论的验证:

第一步:现在函数内的this是一个原型为Person.prototype, 构造函数为Person的对象

//  构造函数的原型
			Person.prototype = {
				say: function (){
					console.log('I am saying');
				}
			}
			//  构造函数
			function Person(){
				this.name ='zsn';
				this.age = 18;
				// 打印this对象的原型
				console.log(this.__proto__);
				// 验证this是否是Person构造函数的实例
			    console.log(this instanceof Person);//true
			}
			new Person();//打印结果如下
			//  Object say: ()__proto__: Object
            // true
            
            Person();//打印结果如下
            //  Window
    		// false

第二步:隐士的将创建的对象this通过return返回

//  构造函数的原型
			Person.prototype = {
				say: function (){
					console.log('I am saying');
				}
			}
			//  构造函数
			function Person(){
				var that = Object.create(Person.prototype);
				
				that.name ='zsn';
				that.age = 18;
				
				return that;
				//提前返回that导致return this无法执行而失效
				
			}
			
			var person = new Person();
			//此处不用new也是可以成功返回一个满足条件的对象,因为显示的返回了that
			console.log(person.name); //zsn
			person.say();//I am saying

ps. 关于显示返回that的问题,当我们用new生成对象,若我们显示return的是一个对象 / 引用值,则会导致return this失效,若返回的是原始值,则return this不会失效

 

3、Object.create(原型); 创建一个继承该原型的实例对象

关于此方法的一些事项:

        (1)、若传参为Object.prototype,则创建的原型为Object.prototype,和 new Object()创建的对象是一样的  

Object.create(Object.prototype) <==> new Object();

        (2)、若传参为空 或者 null,则创建的对象是没有原型的, 导致该对象是无法用document.write()打印会报错,因为document.write()打印的原理是调用Object.prototype.toString()方法,该对象没有原型,也就没有该方法,所以document.write()无法打印

          由此延伸的知识点: 引用值都也是算作是对象,所以都可以用document.write()打印;原始值numebr, boolean, string都有自己对象的包装类,借助此机制也是可以用document.write()打印出的;但undefined 和 null既不是引用值,也没有对应的包装类,所以应该无法打印的,但大家会发现这两个值也是可是用document.write()打印的,因为这两个值被设定为特殊值,document.write()打印其是不用调用任何方法的,而是之直接打印其值。

三、对象的增、删、改、查

1、增:

var obj = {};
			console.log(obj.name); //undefined (不会报错)
			obj.name = 'zsn';
			console.log(obj.name); //zsn

2、删:

var obj = {
				name : "zsn"
			};
			console.log(obj.name); //zsn 
			delete obj.name;
			console.log(obj.name); //undefined

3、改:

var obj = {
				name : "zsn"
			};
			console.log(obj.name); //zsn 
			obj.name = 'obj';
			console.log(obj.name); //obj

4、查:

var obj = {
				name : "zsn"
			};
			// 第一种方法
			 console.log(obj['name']);//zsn 
			//  第二种方法
			console.log(obj.name); //zsn
//p.s.最本质的是第一种方法,因为在使用第二种方法时,后台自动将其转换为第一种字符串的形式来查询 

ps.以上的增、删、改三种操作都只是针对当前对象的属性进行操作,而不会影响到当前对象的原型的属性。而查询是先看看当前对象本身是否设置了该属性,如果当前对象未设置该属性,则再看该对象的原型中是否设置了该属性,若两者都没有,则返回undefined

 

四、包装类:

1、五个原始值:number, string , boolean, undefined, null 其中number, string, boolean是分别拥有自己的包装类,而undefined和null是没有自己的包装类的

2.原始值不是对象,无法拥有自己的属性,但因为的包装类的存在,原始值就好似可以拥有自己的属性了,但其拥有的属性又有点特殊之处,如下用string来举例:

先看一段code

//  str是string类型的,非对象,不能拥有属性,为什么能打印出str.length?
			var str = 'abcd';
			console.log(str.length);//4

上边code中问题的解释:

// 因为每次执行完一条完整js语句后该类型对象的包装类就会将该语句包装,所以也就不会导致报错了,这些都是后台自己写的
			var str = 'abcd';
			// var str1 = new String('abcd');
			console.log(str.length);//4
			//var str1 = new String('abcd');
			//console.log(str1.length);

注意:每次包装类包装完一次完整语句后就会被销毁。(即解释一条语句,用包装类包装一次,然后销毁),这回导致其和正常对象的一些不同之处,如下例子

var str = 'abcd';
			// var str1 = new String('abcd');
			//销毁
			str.len = 4;
			//var str1 = new String('abcd');
			//str1.len = 4;
			//销毁
			console.log(str.len); //undefined
			var str1 = new String('abcd');
			console.log(str.len); //str1为刚创建的对象,其len属性自然为undefiend
			//销毁

一个易错的坑:

// 总之记得'原始值包装类''销毁'这两句话就行
			var str = 'abcd';
			str.length = 2;
			console.log(str);
			console.log(str.length);

                                                                                                                                                            参考:https://www.cnblogs.com/libin-1/p/5911190.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值