javascripts知识点梳理5
this指向
指向window
1 2 3 4
| function fn (){ console.log(this) } fn();
|
1 2 3
| setInterval(function(){ console.log(this) })
|
指向实例对象 obj
1 2 3 4 5
| function fn (name , age){ ... console.log(this) } var obj = new fn ('zs' , 21);
|
this指向对象本身
1 2 3 4 5 6 7
| var obj = { name:'zs', age:12, fn function() { console.log(this)} } obj.fn()
|
事件源
1 2 3
| btn.onclick = function() { }
|
改变this指向
1
| fn.call(obj , 参数1 , 参数2) 对函数调用,同时修改调用时this指向obj
|
1
| fn.apply(obj , [参数1 , 参数2]) 对函数调用,同时修改调用时this指向
|
1 2
| fn.bind(obj, 参数) 永久改变this指向 返回函数副本 不会调用执行 bind后续参数调用时进行实参传入,表示被绑定实参后续参数
|
1 2 3 4 5 6 7
| fun.call({name : 'jack'}); fun.call({name : 'jack'});
var fun2 = fun.bind({name : 'rose'}); fun2(); fun2(); fun2();
|
函数进阶
回调函数
回调函数就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调。
曾经用过的回调函数
当一个固定函数中的代码不确定时使用
1 2 3 4 5 6
| $('#box').fadeIn(1000, function () {}); setInterval(function () {}, 100); btn.on('click', function () {}); arr.sort(function (a, b) { return a - b; });
|
闭包
函数内部变量能被外部使用
对私有变量操作的函数,称之为闭包
原理:不对原函数进行二次调用,而是对函数返回结果进行多次调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function fun() { var num = 100; var obj = { getValue: function() { console.log(num); }, setValue: function() { num++; }, setValue2: function() { num-- } }; return obj; } var result = fun(); result.getValue(); result.setValue(); result.getValue();
|
通过对象可以一次返回多个闭包函数
函数使用方式
函数作为参数
函数作为返回值
自执行函数
可以在自执行函数的形参与实参中写入window , document
可以提高性能
1 2 3 4 5 6 7
| (function(window, document) { console.log(window.num); console.log(window.str);
document.getElementById();
})(window, document);
|
函数方法
函数声明方式
function fun () {}
// 函数声明语句在预解析阶段会进行函数提升,将函数体提升到当前作用域顶端
// 下面的代码在不同的浏览器中具有不同的展现效果
/*if (true) {
function fun () {
console.log('这是if中的函数体');
}
} else {
function fun () {
console.log('这是else中的函数体');
}
}
fun();*/
// 由于函数声明语句会存在一些问题,所以通常推荐使用函数表达式进行函数声明。
// 但是如果执意希望使用函数声明语句:遵循以下规则即可
// 1 不要在if中书写函数声明语句,使用函数表达式
// 2 建议在函数声明后再进行调用
/*var fun;
if (true) {
fun = function () {
console.log('这是if中的函数体');
}
} else {
fun = function () {
console.log('这是else中的函数体');
}
}
fun();*/
函数表达式方式
var fun = function () {};
构造函数方式
var fun = new Function(‘x’, ‘y’, ‘console.log(x, y);’);
函数的属性
fn.name 函数名
fn.length 形参的长度
arguments.callee 可以得到当前函数
arguments 一个函数的参数和其他属性
fn.arguments 用于访问实参,作用和arguments对象相同
fn.caller 用于获取函数的调用位置
1 2 3 4 5 6 7 8 9 10
| function showcallee(a,b) { var c = a + b; console.log(showcallee.name) console.log(showcallee.length) console.log(arguments.callee) console.log(arguments) console.log(showcallee.arguments) return c; } showcallee(1,2);
|
1 2 3 4 5 6 7
| function outer(){ inner(); } function inner(){ console.log(arguments.callee.caller); } outer();
|
函数的方法
call() 用于对函数进行调用,同时可以修改调用时的this指向
apply() 用于对函数进行调用,同时可以修改调用时的this指向
bind()方法不会立刻调用函数,而是在调用bind后返回一个当前函数的副本。
参数1:可以绑定函数副本中的this指向
与call和apply的第二个区别:
call和apply只会在调用时修改一次this的指向,bind会将返回的函数副本中的this永久的设置为指定对象。
立即执行函数
1 2 3 4
| (function (window, document) { console.log(window.num); document.getElementById(); })(window, document);
|
继承
单一继承
函数call方法
函数执行两种方法:1,调用 2,事件驱动
fun.call(); 与fun()完全一致
当传入第一个参数(对象)后,表示设置当前函数内的this指向当前对象,后面按顺序传入实参
函数执行两种方法:1,调用 2,事件驱动
fun.call(); 与fun()完全一致
当传入第一个参数(对象)后,表示设置当前函数内的this指向当前对象,后面按顺序传入实参
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| fun.call()不传参数==fun() fun.call(obj); 传入参数1后,表示设置当前函数内的this指向当前对象。 fun.call(obj, 100, 200) 传入后续参数,用于表示实参。
练习的案例 <script> function people(name, age) { this.name = name; this.age = age;
} people.prototype.sayHi = function() { console.log(this.name + '今年' + this.age + '岁了');
}
function student(name1, age1, banji) {
people.call(this, name1, age1); this.banji = banji; } student.prototype.sayHi1 = function() { console.log(this.name + '今年' + this.age + '岁了');
} var obj = new student('jack', 28, '2班');
console.log(obj); obj.sayHi1(); obj.sayHi(); </script>
|
借用构造函数继承
这种方式可以继承属性,并且可以传入参数,但无法继承方法
在Student中的this指向jack jack也就是student这个函数,
如果将jack传入到call中,意味着修改People函数中的this为jack
这时两个构造函数的this都指向jack
实例
1 2 3 4 5 6 7 8 9 10 11
| function People(name, age) { this.name = name; this.age = age; } function Student(name1, age1, banJi) { People.call(this, name1, age1); this.class = banJi; } var jack = new Student('jack', 21, '2班'); console.log(jack); jack.sayHi();
|
原型继承
People的实例对象拥有People的方法,令Student的原型对象等于一个People的实例对象,之后便可调用People原型对象中的方法.
继承顺序:原函数内>附加函数内>原函数外>附加函数外
单独设置的功能需要在继承操作后设置
由于使用了覆盖方式设置原型constructor被改为People
需要补全constructor属性
Student.prototype.constructor = Student;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function People(name, age) { this.name = name; this.age = age; } People.prototype.sayHi = function() { console.log('你好,我叫' + this.name); }; function Student(name1, age1, banJi) { People.call(this, name1, age1); this.class = banJi; } Student.prototype = new People(); Student.prototype.constructor = Student; var jack = new Student('jack', 21, '2班'); console.log(jack); jack.sayHi();
|
组合继承
将两种单一继承组合,兼顾两者优点
构造函数与原型对象与实例对象的关系
实例对象:通过构造函数创建的,具有一个属性__proto__,指向构造函数的原型对象。
构造函数:具有一个属性prototype,指向构造函数的原型对象。
原型对象:具有一个属性constructor,指向构造函数。
实例对象
function Person(personName) { // 括号内为参数,可以设置多个参数来定制对象。
this.name = personName; // 将传入的personName值赋予name属性
this.info = 'I am called' + this.name; //设置info属性
this.infoShow = function () { // 利用匿名函数添加方法
alert(this.info);
}
}
1 2
| var person1 = new Person('Adam'); var person2 = new Person('Eve');
|
person1 person2 都是 Person 构造函数 的实例对象
原型对象
任何一个JavaScript对象(一般有对花括号)都有一个原型对象,这个原型对象是JavaScript语言内置的,JavaScript对象可以使用原型对象的属性和方法。
实例对象:通过构造函数创建的,具有一个属性__proto__,指向构造函数的原型对象。
构造函数:具有一个属性prototype,指向构造函数的原型对象。
原型对象:具有一个属性constructor,指向构造函数。
原型链
原型链的作用:
// 1 用于描述实例对象与原型对象之间关系的一种方式。
// 2 用于描述对象属性的查找方式(沿原型链向上查找)。
// 原型链的终点:Object.prototype
用于描述实例对象与原型对象之间关系的一种方式
也用于描述对象属性的查找方式(沿原型链向上查找)
递归
可以利用递归进行深拷贝
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| var obj = { name : 'jack', age : 18, aiHao : { qiMa : '我喜欢骑大白马', swim : '我喜欢自由泳', daQiu : { lanQiu : '因为喜欢看NBA,所以也喜欢打篮球', zuQiu : '我喜欢c罗,所以也喜欢踢足球' } }, arr : [1, 2, 3] }; var obj2 = {};
function deepCopy (obj, obj2) { for (var k in obj) { if (typeof obj[k] !== 'object' || obj[k] === null) { obj2[k] = obj[k]; } else { obj2[k] = obj[k].constructor === Array ? [] : {}; deepCopy(obj[k], obj2[k]); } } } deepCopy(obj, obj2); obj.aiHao.qiMa = '我喜欢骑大黑马'; console.log(obj, obj2);
|
FB数列的计算