学习日志 8.12

练习题

			A = {n: 4399};		//声明一个A对象,成员n为4399
			
			var B = function() {
				this.n = 9999
			}				//声明一个B函数,谁调用这个函数创建新对象,则创建属性n为9999
			var C = function() {
				var n = 8888
			}			//声明一个C函数,定义一个n为8888
			B.prototype = A;		
			C.prototype = A; 			//将B,C函数的prototype属性改变为A对象
			var b = new B();		//b{__proto__:{A},n:9999}
			var c = new C();		//c{__proto__:{A}}
			A.n++;				//A = {n: 4400};
			console.log(b.n);		//9999
			console.log(c.n);		//c对象中没有n,所以就去原型对象中找 所以为4400

离它最近的function这个函数是谁代用的 this就是谁 没有function就是window

this new prototype __proto__
			this==>离它最近的function这个函数是谁代用的  this就是谁  没有function就是window
			fn()==>window
			obj.say()==>obj
			xx1.xx2[10].xx3()==>数组中第11个数据 xx1.xx2[10]
			(obj.say)()==>obj
			(obj1.say=obj2.say)==>window
			fn()()===>window

当我们要new一个函数的时候,有三步步骤
new fn()
1.创建一个空对象,把这个对象的__proto__赋值为fn.prototype==>{_proto:fn.prototype}
2.执行fn函数 fn函数内部的this代表创建出来的这个对象
3.fn函数的返回值是基本数据:表达结果就是创建的对象 引用数据的话,表达式结果就是fn的返回值
prototype 和____proto的差别
1.任何引用数据(对象)都有原型对象==>都有__proto__属性
2.任何函数都能够创建对象==>任何函数都有prototype属性
3.函数创建出来的对象 的原型对象不是这个函数对象==>obj.__proto__不是fn函数也不是fn.__proto它是fn.prototype

当我们获取一个对象的数据的时候,会有如下2个过程:
obj.xx==>
1.如果对象自己没有xx 就会去原型上访问,原型没有就去原型的原型上访问
2.直到null没有返回undefined 这个就是原型链
这个一步步往原型的原型上面走的过程,就是我们顺着原型链一直往上爬,最顶点就是null,如果到了最顶点null都没找到这个需要访问的值,那说明就是没有在全局中进行定义了
当我们想初始化一个对象中的数据时
obj.xx=[]
不管原型链上没有xx这个成员 都会给自己添加xx这个成员
obj.xx.操作==>真的会操作原型(做项目基本没有,题)
只修改整个属性只会给自己这一层添加或者赋新值,如果不是修改整个成员,而是该成员内部操作,就会操作原型对象

eg:
obj.__proto__.name1="wangchuan"		//在__proto__成员中添加一个name1属性,赋值为"wangchuan"
obj.__proto__="{name:wangchuan}"		//把整个obj.__proto成员所存的原来的原型对象的地址替换成{name:wangchuan}对象的地址

方法劫持

方法劫持
call apply 使用方法差不多,只有小差别
bind 差距较大

		var obj1={name:"jack",age:18,say:function (arg1,arg2) {
			console.log(arg1,arg2)
			console.log(this.name,this.age)
		}}
		var obj2={name:"xxxxx",age:"xxxx"}
		
		obj1.say()		//jack,18
		obj2.xxx=obj1.say
		obj2.xxx()		//xxxxx,xxxx
		
		obj1.say.call(obj2,100,200)		//.call前面就是正常读,使用obj1的say方法,但是使用的对象为括号里的第一个参数,也就是obj2,达到劫持的效果,使用劫持后,say方法的this全部为obj2,后面的参数为传进去的实参100和200
		
		function fn (arg1) {
			console.log(this)
			console.log(arg1)
		}
					
		fn.call(obj1,"hello")		//直接通过函数来劫持也可以,不一定非要使用对象中的方法进行劫持
		
		fn.apply(obj2,[100])
		obj1.say.apply(obj2,[100,200])    //apply和call的不同在于传进去的实参,call是通过逗号,连接,并以此传入,apply是通过将数据传入数组,然后将这个数组给函数中的argument达到赋值的效果

call apply 函数调用的时候为函数内部指定this对象
bind 方法在设计的时候就为其指定this对象,以后都不能被修改

var obj1={name:"jack"};
			var obj2={name:'karen',say:function() {
				console.log(this)
			}.bind(obj1)}
			
			obj2.say()
			obj2.say.call(window)
			obj2.say.apply(window);		//打印出来都是obj1

因为在定义的时候就绑定了bind,以后无论如何只要这个函数进行使用,那么他的使用对象就是obj1

声明的函数不能直接绑定 只能方法直接绑定(声明式的不能直接绑定,定义式的可以直接绑定 )
意思就是,如果我通过直接写一个方法出来加bind方法不行,但是如果我是在一个对象中,写方法的时候在方法后面加bind就可以

obj1.say1=function() {
				console.log(this)
			}.bind(obj2)		//这样写是可以的
			
			obj1.say1.bind(obj2)  		//这样是不行的
			var str="hello"
			var re=str.charAt(1)
			console.log(re)			//e

将这个字符串每一个字符放入一个数组中,取下标为1的元素,题中为e

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值