02-JS资料

this指向

this是JavaScript语音的关键字。他代表函数运行时,自动生成的一个内部对象,只能在函数内部使用,随着函数使用场合的不同,this的值会发生变化,指向是不确定的,也就是说可以动态改变。但是有一个总的原则,那就是this指向的是调用函数的那个对象

window.onload = () => {
  function fn() {
    console.log(this); //window
  }
  fn();

  function fn() {
    "use strict";
    console.log(this); //undefined
  }
  fn();
  /**
   * 在非严格模式下,未绑定的 this 默认指向全局对象 (window 或 global)。
   * 而在严格模式下,this 不再自动指向全局对象,而是 undefined
   */


  //内置函数this默认指向Window
  function fn() {
    console.log(this);//window
  }
  setTimeout(fn, 1000);

  //回调函数this默认指向Window
  function fn(v) {
    console.log(v);
    console.log(this);//window
  }

  function fn2(callback, value) {
    callback(value);
  }
  fn2(fn, "hello");

  //函数在数组中
  function fn() {
    console.log(this);
  }

  var arr = [fn, 2, 3, 4, { id: 3 }];

  arr[0](); //[ [Function: fn], 2, 3, 4, { id: 3 } ]
  var f = arr[0];
  f(); //window

  //函数在object对象中
  function fn() {
    console.log(this);
  }
  var obj = {};
  obj.name = "xp";
  obj.init = fn;
  obj.init(); //{ name: 'xp', init: [Function: fn] }

  //在构造函数中
  //构造函数定义
  function Person(name, age) {
    this.name = name;
    this.age = age;
    console.log(this);
    this.sayHello = function () {
      console.log(this);
      console.log(this.name);
    };
  }
  //实例化
  var jack = new Person("jack", 20);
  jack.sayHello();
  //创建新的实例,通过new操作符,经历一下步骤:
  //1、创建新对象
  //1、将构造函数作用域赋给这个新对象
  //3、执行构造函数
  //4、返回新对象
};

函数的默认作用域可以修改

call()、apply()、bind()用于改变函数内部this的值

  var id = 1;

  function fn() {

    console.log(this.id);

  }

  fn();

  var item = {id:888}

  item.action = fn;

  item.action();//888

  fn.apply(item);//888 fn中的this指向了item

  fn.call(item);//888

  var a = "global";

  var obj2 = {

    a: 666,

    action: fn,

  };

  obj2.action.apply(window,"vvv",4444);//this指向Window

apply和call的区别:传递参数的方式不同

  var a = "global";
  var fn = function fn(titile,value){
    return `${this.a}-${titile}-${value}`
  }
  fn.call(obj,"call",1);//传参
  fn.apply(obj,["Call",2]);//以数组的方式进行传参
  //bind的使用:bind用于创建一个新的函数,该函数的上下文绑定到指定的对象,但并不会立即执行。
  //bind:返回新的函数,这个新的函数不能再次改变作用域
  var id =1;
  function fn (){
    console.log(this.id);
    
  }
  var item = {
    id:888
  }
  fn.bind(item)();//相当于var f = fn.bind(item);然后执行f()

 /********扩展*********** */
  var n = 200;
  var obj = {
    n: 1,
    render: function () {
      this.n += 1;
      console.log(this.n);
    },
  };

  setInterval(obj.render,1000);//window

  setInterval(obj.render.bind(obj),1000);//obj,obj.render.bind(obj)作用域不会改变
  var length = 100;
  function f1() {
    console.log(this.length);
  }
  var obj = {
    length: 10,
    f2: function (f1) {
      f1();//f1执行的时候,没有明确指明调用者,调用者还是Window
      arguments[0]();//arguments是可变参数,arguments是一个数组,arguments[0]第一个元素是f1方法,
      // 数组中的方法的作用域是数组,所以此时console.log(this.length)打印的是数组长度
    },
  };
  obj.f2(f1, 1);//100,2

事件冒泡

<body>
    <div class="div1">
        div1
        <div class="div2">
            div2
            <div class="div3">
                div3
            </div>
        </div>
    </div>
</body>

function f(name) {
	return document.querySelector(name);
}
f(".div1").onclick = function () {
	console.log("div1");
};
f(".div2").onclick = function () {
	console.log("div2");
};
f(".div3").onclick = function (e) {//event对象
	console.log("div3");
	e.stopPropagation();//使用e.stopPropagation()对事件冒泡进行阻止
};

Event事件对象

阻止事件冒泡:e.stopPropagation()对事件冒泡进行阻止
Event事件对象
event.target或者event.currentTarget
event.target:事件发生源
event.currentTarget:绑定事件的元素
两者的区别:div3点击,但是可能没有绑定onclick事件,由于事件冒泡,div2绑定了onclick事件,这时候事件源target是div3,
事件currentTarget是div2

事件委托

把一个元素的响应时间委托到其他元素上执行

<ul id="list">
    <li>111</li>
    <li>222</li>
    <li>333</li>
    <li>444</li>
    <li>555</li>
</ul>

  var list = document.getElementById("list");
  var li = list.getElementsByTagName("li");
  for (let index = 0; index < li.length; index++) {
    const element = li[index];
    element.onclick = function () {
      this.style.color = "red";
    };
  }
  //上面需要每一个节点进行注册事件,下面直接将事件注册给父元素
  var list = document.getElementById("list");
  list.onclick = function (e) {
    if (e.target.nodeName === "LI") {
      e.target.style.color = "red";
    }
  };

创建对象的方式

原型

用原型实例指向创建对象的类,使用于创建新的对象的类的共享原型的属性与方法

可以给构造函数对象定义一个原型对象,这个原型对象能够继承给所有被new创建出来的对象上

  function Person(name, age) {
    this.name = name;
    this.age = age;
  }
  Person.prototype.msg = "hello"; //在原型对象上添加任意属性
  Person.prototype.action = function () {
    console.log(`${this.name}~${this.msg}`);
  };
  var p = new Person("xp", 777);
  console.log(p); //{ name: 'xp', age: 777 }
  console.log(p.msg); //直接获取原型上的属性,如果构造函数有这个属性,就不去原型上查找
  console.log(p.action()); //直接获取原型上的方法

哪些对象拥有原型对象?

JS对象分为2种,普通对象Object和     

prototype是函数有的属性

    

普通对象和函数对象的区别:凡是通过new Function创建的对象都是函数对象,其他都是普通对象(通常通过Object创建),可以通过typeof来判断

普通对象(Object)

1、使用字面量定义:var obj = {};

2、使用构造函数定义:var obj = new Object();

3、使用Object.create()方法:var obj = Object.create(null);

函数对象(Function)

1、使用函数声明定义:function func() {}

2、使用函数表达式定义:var func = function() {};

3、使用Function构造函数定义:var func = new Function();

  function f() {}
  typeof f;//function,函数对象,这个可以通过new Function()来创建
  var o = {}
  typeof o;//普通对象:object

  function F() {}
  var o1 = new F();
  typeof o1;//普通对象:object

1、每一个函数对象都有一个prototype属性,但是普通对象是没有的;prototype下面又有个constructor,指向这个函数。
2、每个对象都有一个名为__proto__的内部属性,指向它所对应的构造函数的原型对象,原型链基于__proto__;

  function Cat(name, color) {
    this.name = name;
    this.color = color;
  }
  Cat.prototype.type = "animal";
  Cat.prototype.eat = function () {
    console.log("吃老鼠");
  };
  var Jack = new Cat("jack", "white");
  var Tom = new Cat("tom", "black");
  typeof Jack.constructor;//Jack被谁构造出来的,也就是Cat的函数对象   
  //通过普通对象修改原型对象的值
  Jack.__proto__.type = "888";
  Tom.type ;//888

  原型链

/************************原型链******************************* */
  function Animal() {
    this.type = "animal";
    this.hobby = ["吃", "睡"];
  }
  Animal.prototype.xyz = "xyz"; 
  function Cat(name, color) {
    this.name = name;
    this.color = color;
  }
  Cat.prototype = new Animal(); //通过原型对象让两个对象产生关系
  var Jack = new Cat("jack", "white");
  var Tom = new Cat("tom", "black");
  Jack.type; //animal
  Jack.xyz; //xyz
  Jack.__proto__.hobby[1] = "玩"; //修改原型对象的值
  Jack.__proto__.__proto__.xyz = "999"; 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值