当前位置: 首页 > 工具软件 > marty.js > 使用案例 >

JS__this,arguments,克隆,三目运算符__渡一

公孙令秋
2023-12-01

this

  1. 函数预编译过程 this --> window
function test(c) {
	//var this = Object.create(test.prototype);
	//{
	//__proto__ : test.prototype
	//}
	var a = 123;
	function b() {}
}
AO {
	arguments : [1],
	this : window,//GO 全局
	c : 1,
	a : undefined,
	b : function () {}
}
test(1);
new test();//隐式this指向原型
function test() {
	console.log(this);
}
test();//window{} --> 全局
  1. 全局作用域里 this --> window
this //window{}
  1. call/apply 可以改变函数运行时this指向
  2. obj.func(); func()里面的this指向obj
var obj = {
	a : function () {//方法
		console.log(this.name)
	},
	name : 'abc'
}
obj.a();//谁调用a方法,方法中的this就是谁 this-->obj

试题:

1.var name = "222";
var a = {
	name : "111",
	say : function () {
		console.log(this.name);
	}
}
var fun = a.say;//函数引用
fun()//222 函数在全局中执行 this-->window
a.say()//被调用 111
var b = {
	name : "333",
	say : function (fun) {
		//this --- > b
		fun();//没有被调用就是全局 走预编译环节 function () {console.log(this.name);} this --> window
	}
}
b.say(a.say);//222
b.say = a.say;//a.say的函数拷贝到b.say的函数替换掉
b.say();//被调用 333

总结: 没人调用就是全局

2.var foo = '123';
function print(){
	var foo = '456';
	this.foo = "789";
	console.log(foo);
}
print();//this-->window 456
变式1:
var foo = 123;
function print() {
	this.foo = 234;//this-->window 
	console.log(foo);//打印的是全局的foo,全局的foo被更改为234
}
print();//234
变式2:
var foo = 123;
function print() {
	//var this = Object.create(print.prototype) this不指向window
	this.foo = 234;
	console.log(foo);//打印的是全局的foo,全局的foo未被更改
}
new print();//123

3.运行 test() 和 new test()的结果分别是什么?
var a = 5;
function test() {
	a = 0;
	alert(a);//0
	alert(this.a);//5
	var a;
	alert(a);//0
}
test();
AO {
	a : 0,
	this : window
}
function test() {
	var this = {
		__proto__ : test.prototype;
	}//里面没有a
	a = 0;
	alert(a);//0
	alert(this.a);//undefined
	var a;
	alert(a);//0
}
new test();
AO {
	a : 0,
	this : {} 
}

笔试真题

1.预编译:函数声明整体提升
var x = 1, y = z = 0;
function add(n) {
	return n = n + 1;
}
y = add(x);//4
function add(n) {
	return n = n + 3;
}
z = add(x);//4

2.以下哪些是javascript语言typeof可能返回的结果:  AC
//boolean,number,string,undefined,object,function
A.string
B.array
C.object
D.null

3.看看下面alert的结果是什么
function b(x, y, a) {
	arguments[2] = 10;//a
	alert(a);//10
}
b(1, 2, 3);//实参列表的每一位和形参列表的每一位相互映射
如果函数体改成下面,结果又会是什么?
a = 10;
alert(arguments[2]);//10

4.逗号操作符,只返回后边的那个
var f = {
	function f() {
		return "1";
	},
	function g() {
		return 2;
	}
)();
typeof f;//number

5.
var x = 1;
if(function f() {}) {//true 函数转换成表达式,放在括号里的f外部找不到
	x += typeof f;//"undefined"
}
console.log(x);//"1undefined"

6.以下哪些表达式结果为true:  AD
A.undefined == null//true NaN不等于任何数包括它本身
B.undefined === null//false 不绝对等于,NaN也不绝对等于它自身
C.isNaN("100")//false 经历Number隐式类型转换
D.parseInt("1a") == 1;//true

{} == {} //false 一个对象代表一个房间,引用值比较地址,地址相等才相等
var obj1 = obj;//指向同一个房间
obj1 == obj//true

7.请阅读以下代码,写出以下程序的执行结果:
function print() {
	console.log(foo);
	var foo = 2;
	console.log(foo);
	console.log(hello);
}
print();   执行结果:Error:hello is undefined

8.请阅读以下代码,写出以下程序的执行结果:
function print() {
	var test;//被function覆盖
	test();
	function test() {
		console.log(1);
	}
}
print();//1

9.请阅读以下代码,写出以下程序的执行结果:
function print() {
	var x = 1;
	if(x == "1") console.log("One!");//发生隐式类型转换
	if(x === "1")console.log("Two!");//不发生隐式类型转换
}
print();//One

10.请阅读以下代码,写出以下程序的执行结果:
function print() {
	var marty = {
	 	name : "marty",
	 	printName : function() {
	 		console.log(this.name);
	 	}
	}
	var test1 = {
		name :"test1"
	};
	var test2 = {
		name :"test2"
	};
	var test3 = {
		name :"test3"
	};
	test3.printName = marty.printName;
	var printName2 = marty.printName.bind({name:123});
	marty.printName.call(test1);//test1
	marty.printName.apply(test2);//test2
	marty.printName();//marty
	printName2();//
	test3.printName();//test3
}
print();

11.请阅读以下代码,写出以下程序的执行结果:
var bar = {a : "002"};//{a : 'a'}
function print() {
	bar.a = 'a';
	Object.prototype.b = 'b';
	return function inner() {
		console.log(bar.a);//a
		console.log(bar.b);//b
	}
}
print()();//第一个()返回函数inner 第二个()执行函数inner

arguments

  1. arguments.callee指向函数自身引用
function test() {
	console.log(arguments.callee == test);//true
}
test();

立即执行函数不具备名称,如果想递归调用,函数引用写什么呢?arguments.callee可以解决问题

var num = (function(n){
    if(n == 1){
        return 1;
    }
    return n * arguments.callee(n-1);
}(20));
function test() {
	console.log(arguments.callee);//test
	function demo() {
		console.log(arguments.callee);//demo
	}
	demo();
}
test();
  1. func.caller-- func被调用的环境是? caller不是arguments上的属性,而是函数自己的属性
    ES5标准模式下会报错
function test() {
	demo();
}
function demo() {
	demo.caller;//test
}

克隆

  1. 浅层克隆:克隆体obj1的属性改变会联动obj同时改变。
var obj = {
	name :  'abc',
	age : 123,
	sex : 'female',
	card : ['visa','unionpay']
}
var obj1 = {}
function clone(origin, target) {
	var target = target || {};//兼容性
	for(var prop in origin) {
		target[prop] = origin[prop];
	}
	return target;
}
clone(obj, obj1);
obj1.card.push('master');
//obj1.card—->['visa','unionpay','master']
//obj.card—>['visa','unionpay','master']

2.深层克隆:克隆相同的属性,但是房间不一样,改变其中一个不会联动改变另一个。
分析环节:引用值只考虑数组和对象。循环判断,遇到数组和对象都要判断。

var obj = {
    name : "abc",//原始值
    age : 123,//原始值
    card : ['visa', 'master'],//引用值
    wife : {
        name : "bcd",
        son : {
            name : "aaa"
        }
    }
}
var obj1 = {
    name : "abc",//obj.name
    age : 123,
    card : [obj.card[0],obj.card[1]],
    wife : {
        name : "bcd",
        son : {
            name : "aaa"
        }
    }
}
//遍历对象  for(var prop in obj) 数组也能for in,数组是特殊的对象 prop代表下标
// 1.判断是不是原始值 typeof()—->object
// 2.判断是数组还是对象(引用值) toString instanceof和constructor在父子域那块儿有问题
// 3.建立相应的数组或对象
// 4.递归

先判断obj属性的值类型,过滤出object类型(null也需要考虑到),使用toString方法区分数组和对象,递归调用原函数。

var obj = {
    name : 'abc',
    age : 123,
    gender : 'male',
    card : {
         card1 : 'visa',
         card2 : 'master'
    }
};
var obj1 = {};
function deepClone(origin, target){
  	var target = target || {},//容错,以防用户没有传target参数
    toStr = Object.prototype.toString,
    arrStr = "[object Array]";
    for(var prop in origin){
    	if(origin.hasOwnProperty(prop)){//判断是不是自己的属性,避免拿原型链上的属性
    		if(origin[prop] !== 'null' && typeof(origin[prop]) == 'object'){//判断 绝对不等于null,typeof是object-->引用值
	            // if(toStr.call(origin[prop]) == arrStr){//判断是对象还是数组
	            //     target[prop] = [];//建立相应的数组和对象
	            // }else{
	            //     target[prop] = {};
	            // }
	            target[prop] = (toStr.call(origin[prop]) == arrStr) ? [] : {};			
	            deepClone(origin[prop], target[prop]);
        	}else{//判断 原始值 出口
            	target[prop] = origin[prop];
        	}
    	}	
	}
    return target;
}
deepClone(obj, obj1);
//obj.card.push('abc')
//obj1.card-->["visa","master"]

三目运算符

条件判断?是 :否 并且会返回值

        var num = 1 > 0 ? 2 + 2 : 1 + 1;//4
        var num = 1 > 0 ? ("10" > "9" ? 1 : 0) : 2; //0 里面()逐位比ASCI码
 类似资料: