264 lines
6.0 KiB
JavaScript
264 lines
6.0 KiB
JavaScript
// 只要这个函数是以普通函数的形式被调用
|
||
// function fn1(){
|
||
// console.log(this); // 指向全局对象
|
||
// }
|
||
// fn1();
|
||
|
||
// 如果是严格模式,那么 this 的值为 undefiend
|
||
// function fn2(){
|
||
// 'use strict'
|
||
// console.log(this);
|
||
// }
|
||
// fn2();
|
||
|
||
// 上面介绍了以函数的形式调用,this 的指向
|
||
// 这种题目有一种变形
|
||
// var foo = {
|
||
// bar : 10,
|
||
// func(){
|
||
// console.log(this);
|
||
// console.log(this.bar);
|
||
// }
|
||
// }
|
||
// var fn2 = foo.func;
|
||
// fn2();
|
||
// foo.func();
|
||
|
||
// 如果一个函数是以对象的方法的形式被调用
|
||
// 那么 this 指向该对象
|
||
// var stu = {
|
||
// name : "zhangsan",
|
||
// fn(){
|
||
// return this;
|
||
// }
|
||
// }
|
||
// console.log(stu.fn() === stu);
|
||
|
||
// var stu = {
|
||
// name : "zhangsan",
|
||
// son : {
|
||
// name : "zhangxiaosan",
|
||
// fn(){
|
||
// return this.name;
|
||
// }
|
||
// }
|
||
// }
|
||
// console.log(stu.son.fn());
|
||
|
||
// var o1 = {
|
||
// text : 'o1',
|
||
// fn(){
|
||
// return this.text;
|
||
// }
|
||
// }
|
||
|
||
// var o2 = {
|
||
// text : 'o2',
|
||
// fn(){
|
||
// return o1.fn();
|
||
// }
|
||
// }
|
||
|
||
// var o3 = {
|
||
// text : 'o3',
|
||
// fn(){
|
||
// var fn2 = o1.fn;
|
||
// return fn2(); // 这里就相当于是普通函数的形式被调用
|
||
// }
|
||
// }
|
||
// console.log(o1.fn()); // o1
|
||
// console.log(o2.fn()); // o1
|
||
// console.log(o3.fn()); // undefined
|
||
|
||
// call
|
||
// A.call(B)
|
||
// A 通常是一个方法(函数)
|
||
// B 通常是一个对象
|
||
// 调用 A 方法,但是 this 指向 B 这个对象
|
||
|
||
// var obj = {};
|
||
// function fn(){
|
||
// return this;
|
||
// }
|
||
// console.log(fn() === global);
|
||
// console.log(fn.call(obj) === obj);
|
||
|
||
// 下面的情况,this 指向全局对象
|
||
// console.log(fn.call());
|
||
// console.log(fn.call(null));
|
||
// console.log(fn.call(undefined));
|
||
// 总之,this 就指向你传入进去的对象
|
||
|
||
// console.log(fn.call(true));
|
||
|
||
// call 第一个参数是 this 指向的对象
|
||
// 之后的参数就是参数列表,这些参数会传递给前面的方法
|
||
// function add(a, b){
|
||
// return a + b;
|
||
// }
|
||
// console.log(add.call(null, 1, 2));
|
||
|
||
// call 一个经常的应用,就是调用原生的方法
|
||
|
||
// var obj = {};
|
||
// hasOwnProperty 该方法是查看一个对象是否有某一个属性或者方法
|
||
// 这个属性或者方法必须是自身就有的,而不是继承而来
|
||
// console.log(obj.hasOwnProperty('toString')); // false
|
||
// console.log(obj.toString()); // [object Object]
|
||
|
||
// 通过上面的例子,我们可以知道
|
||
// obj 能够调用 toString,但是 toString 这个方法并不是他自身所拥有的
|
||
// 来自于它的原型对象上面
|
||
|
||
// obj.hasOwnProperty = function(){
|
||
// return 'aaaaa';
|
||
// }
|
||
// console.log(obj.hasOwnProperty('toString')); // aaaaa
|
||
|
||
// 上面我们对 hasOwnProperty 这个方法进行了覆盖
|
||
// 使用 call 可以调用原生的方法
|
||
// console.log(Object.prototype.hasOwnProperty.call(obj, 'toString'));;
|
||
|
||
// apply
|
||
// 该方法和 call 基本上一模一样
|
||
// 区别仅仅是后面参数的区别,call 后面是参数列表
|
||
// 而 apply 后面是一个参数数组
|
||
|
||
// 使用 apply 调用原生方法
|
||
|
||
// var arr = [1, 2, 3, 4, 5];
|
||
|
||
// console.log(Math.max.apply(null, arr));
|
||
|
||
// console.log(Array.prototype.slice.apply({ 0: 1, 1: 2, 2: 3 }));
|
||
// console.log(Array.prototype.slice.apply({ 0: 1, 1: 2, 2: 3, length:3 }));
|
||
// console.log(Array.prototype.slice.apply({ 0: 1, 1: 2, 2: 3, length:5 }));
|
||
// console.log(Array.prototype.slice);
|
||
|
||
// bind 绑定 this 指向,返回一个新的函数
|
||
|
||
// var d = new Date();
|
||
// console.log(d);
|
||
// console.log(d.getTime());
|
||
|
||
// var fn = d.getTime;
|
||
// fn();
|
||
// 上面的调用方式,使得 this 指向了全局对象,而非 Date 实例对象
|
||
// 下面使用 bind 来绑定
|
||
|
||
// var fn = d.getTime.bind(d);
|
||
// console.log(fn());
|
||
|
||
// bind 示例2
|
||
// var counter = {
|
||
// count : 0,
|
||
// add(){
|
||
// this.count++;
|
||
// }
|
||
// }
|
||
// var obj = {
|
||
// count : 100
|
||
// }
|
||
// var fn = counter.add.bind(obj);
|
||
// fn();
|
||
// console.log(counter.count);
|
||
// console.log(obj.count);
|
||
|
||
|
||
// var counter = {
|
||
// count : 0,
|
||
// add(){
|
||
// 'use strict'
|
||
// this.count++;
|
||
// }
|
||
// }
|
||
|
||
// function callback(fn){
|
||
// fn();
|
||
// }
|
||
|
||
// callback(counter.add);
|
||
// console.log(counter.count); // 1
|
||
|
||
// var obj = {
|
||
// name : "zhangsan",
|
||
// arr : [1,2,3],
|
||
// print(){
|
||
// this.arr.forEach(function(n){
|
||
// console.log(this.name);
|
||
// console.log(this === global);
|
||
// }.bind(this))
|
||
// }
|
||
// }
|
||
// obj.print();
|
||
|
||
// bind 方法结合 call 方法使用
|
||
|
||
|
||
// console.log([1, 2, 3].slice(0, 1));
|
||
|
||
// slice 方法来源于 Array.prototype
|
||
|
||
// console.log(Array.prototype.slice.call([1, 2, 3], 0, 1));
|
||
|
||
// call 方法来源于 Function.prototype
|
||
// var slice = Function.prototype.call.bind(Array.prototype.slice);
|
||
// 这里就相当于改写了 slice 方法
|
||
// 以前用 slice 方法 [1,2,3].slice(0,1)
|
||
// console.log(slice([1,2,3], 0, 1));
|
||
|
||
// function fn(){
|
||
// console.log(this.v);
|
||
// }
|
||
|
||
// var obj = {
|
||
// v : 123
|
||
// }
|
||
|
||
// var func = Function.prototype.call.bind(Function.prototype.bind);
|
||
// func(fn, obj)();
|
||
|
||
|
||
// 箭头函数 this 指向
|
||
// var x = 20;
|
||
// const obj = {
|
||
// x: 10,
|
||
// test: () => {
|
||
// console.log(this); // {}
|
||
// console.log(this.x); // undefined
|
||
// }
|
||
// }
|
||
// obj.test();
|
||
|
||
// var obj = {
|
||
// name: '张三',
|
||
// times: [1, 2, 3],
|
||
// print: function () {
|
||
// this.times.forEach((n)=>{
|
||
// console.log(this.name);
|
||
// });
|
||
// }
|
||
// };
|
||
|
||
// obj.print()
|
||
|
||
// var name = "JavaScript";
|
||
// const obj = {
|
||
// name: "PHP",
|
||
// test: function () {
|
||
// const i = ()=> {
|
||
// console.log(this.name);
|
||
// // i 是以函数的形式被调用的,所以 this 指向全局
|
||
// // 在浏览器环境中打印出 JavaScript,node 里面为 undeifned
|
||
// }
|
||
// i();
|
||
// }
|
||
// }
|
||
// obj.test();
|
||
|
||
// 箭头函数不能作为构造函数
|
||
const Test = (name, age) => {
|
||
this.name = name;
|
||
this.age = age;
|
||
};
|
||
const test = new Test("xiejie", 18); |