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{} --> 全局
this //window{}
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
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();
function test() {
demo();
}
function demo() {
demo.caller;//test
}
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码