学习日志 8.8

一.复习

关于this:

		// this

离this最近的function(嵌套)这个单词(没有这个单词直接就是wind),是哪个对象让它的代码跑起来的,this就是那个对象
感觉this之前不太清楚的问题就是我总是从外部开始看一步一步的走到this那一步去,昨天晚上想清楚了后个人感觉从this那一步往外推才是更加容易理清楚,首先牢记this的肯定是一个对象,先找到那个对象是那一串,通过从外面一路点语法和取下标方式找到那个对象,那个如果我就单纯的访问到那一步函数,然后前面都不是对象来进行的,那么this的就是window
关于new:
1.创建对象 ==> {}
2. 用这个创建的对象调用构造函数

3.new函数小括号 这个表达产生结果
基本数据===>就是这个构造过的对象
引用数据==>就是返回值

二.原型对象

我们刚新建一个对象的时候,为什么可以通过其他的语法读取到里面的值,为什么数组[ ]可以通过很多办法获取到里面的值,并且还能知道其长度,我们在定义这个对象的时候明明没有声明这些函数,这是因为系统会在我们定义的基础上添加一些功能,这些功能是一个代码块,里面有很多读取呀,写入之类的代码,这个代码块是以一个对象的形式存在,我们叫这个对象为原型对象
每一个对象的建立都是在系统或者直接定义的原型对象上面扩展的,

在这里插入图片描述
1.构造函数的第一个字母(没有规定必须大写,但是一般为了跟普通的函数区别开,要大写)
2.每一个函数都有一个属性叫length 是形参的个数(形参个数和实参个数不一定一样多)
3.每一个函数都有一个属性叫prototype==>每一个对象(引用数据)都有一个__proto__
(1).如果把它当做普通函数调用,prototype这个属性就没有什么用
(2).如果用new关键字来调用函数,这个prototype属性指向的对象就是创建的对象的原型对象
(3).把prototype属性指向的对象 放在扩展对象的__proto__属性中
(4).我们称一个对象的__proto__属性指向的对象为这个对象的原型对象

	function fn (name1) {
				this.name=name1
				this.life=1
			}		//这是一个构造函数,形参为name1,构造出来的对象的name为形参name1中的值,对象的life为1
			var obj={name:"爸爸",life:1};		//定义一个"爸爸"对象
			fn.prototype=obj		//让fn的prototype属性为obj这个对象
			var f1=new fn("marry")		//新建一个f1对象,调用构造函数fn,这个对象的name为marry,life为1,但是这个对象中的__proto__属性已经变成了obj这个对象了
			
			var f2=new fn("jack")		//同理
		
			console.log(f1){__prto__:obj,name:"marry",life:1}
			console.log(f2)	//{__prto__:obj,name:"jack",life:1}
			console.log(f1.__proto__)//={name:"爸爸",life:1};
			console.log(f2.__proto__)//={name:"爸爸",life:1};
			console.log(fn.prototype)//={name:"爸爸",life:1};
			

关于原型函数:
我们创建的一个新对象,是有原型函数这是我们都知道的了,但是这个原型函数同样是由其他的原型函数构建而成,一步接一步,类似于道生一,一生二,二生万物的这种道理,从而我们返回去推算,则得到了最原始的这个原型函数,null
关于赋值这个操作:
赋值这个操作涉及到两个步骤
1.获取这个被赋值的成员:先去自己的扩展空间里面的成员,如果有同名的就是他了,如果没有找到,则去__proto__中去找,如果一直没找到null都没有找到这个成员,那么则取到undefined
2.设置值
如果我们要给其赋值,那么不管原型上有没有这个成员,我们都会在自己的拓展空间中新建这个成员,并且赋予值,这一步一旦完成,则无法通过这个对象获取到其原型空间的这一个成员的信息,因为在拓展空间中就能找到这个成员,第一步就不会往下寻找

function father (name) {
				this.name=name
				this.life=1
				this.money=50000
			}		//定义一个构造函数father
			function son (name) {
				this.name=name
			}	//定义一个构造函数son
			
			var f1=new father("爸爸")	//用father构造函数构造一个f1,名字为"爸爸",life为1,money为5000.
			son.prototype=f1			//将son这个构造函数的prototype属性替换为f1这个对象,经过这一步得出以后使用这个构造函数构造出来的对象,其中的__proto__属性为{name:"爸爸",life:1,money:5000}
			
			var s1=new son("jack")		//使用son这个构造函数构造s1,通过这个构造函数,this.name为jack,这个属性虽然在其__proto__属性中有,但是会在其开拓空间重新生成这个成员
			var s2=new son("marry")			同理
			var f2=new father("爸爸2")	//father这个构造函数没有变化所以和f1一样
			
			console.log(s1)
			console.log(s2)
			console.log(f1)
			console.log(f2)
			
			
			console.log(s1.name)
			console.log(s1.money)
			console.log(s1.xxxxxx)

如果我们没有对构造函数添加prototype属性,那么系统会帮我们内置一个空的对象,这个对象是空的,但是其中有__proto__属性,如果一个构造函数是系统给我们提供的例如var arr=new Array(),这也是一个构造函数,用Array来构造了一个arr数组,那么这个arr的__proto__属性必然和Array这个系统为我们提供的构造函数的prototype属性是同一个原型对象,我们只能修改这种系统为我们提供的函数的成员,不能全部进行替代,因为如果我们进行了替代Array,那么我们系统中所有要使用Array来构建的数组都不会被正确的构建,系统就崩溃了,为了避免这种情况,当我们想要去替换的时候,那一串代码就会因为权限不够而不能被正确的执行出来
如果我们自己写了一个构造函数,那么其prototype属性则可以随意修改
如果我们想要修改一个对象的原型对象的时候,只能通过构建函数中的prototype或者用这个原型对象拓展出来的对象的__proto__属性进行修改
但是常常使用prototype来修改原型对象,当不知道对象的构造函数时可以使用__proto__
拓展知识:但是如果访问到原型上的数据自己改自己就可以修改原型上的数据

创建对象的直接量的方式等价于构造函数创建的方式

	var arr=new Array()
	var arr1=[]//语法糖

和两种构建的方法是等价的,下面一种是语法糖,方便快捷,少写字

			Array.prototype={name1:"xxxx"}; //这行代码想要将array里的prototype完全修改,所以这一行代码完全无效,权限不够
			Array.prototype.xxx="hqyj"		//为array的原型对象中新建了一个xxx属性,为"hqyj"	
			var arr1=new Array()	//新建一个arr1对象
			arr1.__proto__.xxx2="cd"		//通过arr1的_proto_来添加一个xxx2属性,为"cd"
			console.log(arr1)		//{[ ],_proto_:{xxx:"hqyj",xxx2:"cd"......}}
			console.log(arr1.name1)		//因为无效而且原型对象中没有name1这个属性,所以为undefined
			console.log(arr1.xxx)		
			var arr1=[]
			arr1.__proto__.xxx2="cd"
			var arr2=[100,200]
			var re=arr2.xxx2
			console.log(arr2)

这主要考点是通过new出来的对象修改原型对象,然后再用原型对象来拓展新对象的时候,也会出现修改后的属性
如果我想通过对象来修改其原型对象的值是不可以的除非是我自己修改我自己
因为如果是我想修改原型对象的属性,那么我的对象必然不能有和这个属性一样的属性名,如果有,那么进行修改的时候直接回修改拓展对象上面的值,根本都不会往原型上去读取,但是如果我没有,那么这个步骤就会帮对象新建一个属性,属性名字为我想修改的那个属性,所以是没有办法的
那么除非什么情况呢

// fn.prototype.com={xx:666}//[101233,1,23,12,31,2]
			// var f1=new fn()//{__proto__:{com:[101233,1,23,12,31,2]}}
			// f1.com=[100]
			// console.log(f1)
			
			// var f2=new fn()
			// // f2.com.push(6666)//为数组末尾添加一个新元素
			// f2.com.age="18"
			// console.log(f2.com)
			
			// var f3=new fn()
			// console.log(f3)

三.作用域

es5==>作用域
没有函数就不谈作用域
一个标识符,在哪些写代码的地方能够使用,这写地方就是这个标识符能够起作用的区域,称为作用域
在script脚本中的变量(window的属性),全局变量
局部作用域,函数内部的变量,只能在函数内部访问
函数里面能访问里面和函数外面的标识符
外面不能访问里面的标识符

		声明提前:
		显示提前到当前作用域的第一行
		隐式提前,提前到全局去
var a=30
			function fn () {
				var a=200
				return {say:function() {
					console.log(a)
				}}
			}
			var a=30
			var obj=fn()
			obj.say()		//200

和this不同:
是去它声明的作用域下执行代码,不是去调用的作用域执行代码,简而言之就是,自己在使用变量的前后找,如果有,就是那个值,如果没有就去外层找,和谁调用的没有关系

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值