js进阶--this指向,构造函数,设计模式,原型与原型链04

this

在全局作用域下this就是window
console.log(this);//window
函数执行的时候,看前面是否有.如果有this就是.前面的,如果没有就是window(非严格模式下),在严格模式下(undefined)
 //"use strict";严格模式,此时注释掉了
function fn(){
    console.log(this);
}
var obj={
    "name":"li",
    fn:fn
}

obj.fn();//{ name: 'li', fn: [Function: fn] }
fn();//window     如果是严格模式就是undefined
给元素绑定事件的时候,当事件触发,函数执行的时候,里面的this就是当前点击元素
ele.onclick=function(){
console.log(this);//当前点击的元素
}
自执行函数中的this是window(非严格模式下),在严格模式下为undefined
(function(){
console.log(this);//非严格模式下为window,严格模式下为undefined
})()
回调函数,无论是严格模式还是非严格模式,他的this都是window
"use strict"
setTimeout(function(){console.log(this);},1000);//window
什么是回调函数?

把一个函数当成一个参数传给另一个函数,例如:

"use scrict"
function fn(callback){
console.log(this);//undefined
callback();
}
fn(function(){console.log(this)});//undefined
//严格模式下是undefined  非严格是window*2
构造函数(类)中的this指的就是当前的实例
function fn(name){
    this.name=name;
}
var f1=new fn("1");//{name:"1"}
var f2=new fn("2");//{name:"2"}
console.log(f1,f2,fn);//{name:"1"} {name:"2"} fn(name){this.name:name;}
通过bind,call,apply可以改变this的指向
  function fn(){
      console.log(this);
  }
  var obj={
      name:"li",
      fn:fn
  }
  fn.call(obj);//{ name: 'li', fn: [Function: fn] }
  fn.apply(obj);//{ name: 'li', fn: [Function: fn] }
箭头函数中没有this也没有arguments,但是在箭头函数中用到this会向上级查找
demo练习
var num=10;
var obj={num:20};
obj.fn=(function(num){
   this.num=num*3;
   num++;
   return function(n){
       this.num+=n;
       num++;
       console.log(num);
   }
})(obj.num);
var fn=obj.fn;
fn(5);//22 这里的this是window
obj.fn(10);//23 这里的this是obj
console.log(num,obj.num)//65 30

单例设计模式

单例模式:可以把描述一个事物的所有属性放到一个对象中,这样避免了相互的干扰,这种设计模式就是单例设计

var obj1={
    name:"cui",
    sex:"男"
}
var obj2={
    name:"yang",
    sex:"男"
}
高级单例模式
var utils=(function(){
函数.........
return {
    name:"yang",
    sex:"男"
}
})()
utils.name;

工厂模式(函数封装)

将一个重复执行的事,封装成一个函数

function person (name,age,sex){
    return {
        name:name,
        age:age,
        sex:sex
    }
}
var p1=person("李",12,"男");
var p1=person("王",18,"女");

构造函数

当函数执行的时候,前面一旦加了new,就变成了构造函数(类)
f1,f2变成了实例,实例是对象数据类型
如果函数执行的时候没有形参,可以把()省去
实例和实例是不相等的,空间地址不同
在构造函数中,通过this添加的属性名和属性值都是添加给了当前的实例,且都是私有的,构造函数中的this就是当前实例,

function fn(){
    return 1;
}
var f1=new fn();
var f2=new fn();
console.log(f1,f2,fn);
构造函数执行的过程
  1. 形成一个私有作用域
  2. 形参赋值
  3. 变量提升
  4. 独有的,开辟一个堆内存,并且把函数里面的this指向这个堆内存(隐形的)
  5. 代码自上而下执行
  6. 把这个对象return返回(隐形的)
构造函数中的return
构造函数中一般情况下不要写return,如果写了,注意:
  • 如果return基本数据类型就不会覆盖原来的
  • 如果return引用数据类型,实例的结果就会改变为手动return的那个引用数据类型
  • 如果只写return,那么不会覆盖原来的
function fn(name){
    this.name=name;
}
var f1=new fn("li");
console.log(f1)//{name:"li"}

function fn(name){
    this.name=name;
    return {age:18}
}
var f1=new fn("li");
console.log(f1)//{age:18}

function fn(name){
    this.name=name;
    return 1;
}
var f1=new fn("li");
console.log(f1)//{name:"li"}

function fn(name){
    this.name=name;
    return
}
var f1=new fn("li");
console.log(f1)//{name:"li"}
判断是否属于一个类

用法:实例 instanceof 类
返回结果:布尔数据类型,true就属于,false不属于

function fn(){
    return 1;
}
var f1=new fn();
console.log(f1 instanceof fn);//true
判断某个对象是否拥有某个属性in

用法:属性名 in 对象名
结果:布尔

检测某个属性是不是对象私有的hasOwnProperty

用法: 对象.hasOwnProperty(“属性名”)
返回值:布尔,不是私有的或者属性不存在都为false,是私有的就是true

function Fn(name,age){
    this.name=name;
    this.age=age;
}

var f1=new Fn("lili",18); 
f1.hasOwnProperty("name");// true
f1.hasOwnProperty("toString");//fasle
创建数组的两种方式及注意事项

使用构造函数时,new Array()里的值如果有1个就是数组的长度(且每个项都为empty空的),如果有多个就是数组的每个项

var ary1=[1,2,3];
var ary2=Array(1,2,3);
var ary3=Array(5);
console.log(ary1,ary2,ary3)//[ 1, 2, 3 ] [ 1, 2, 3 ] [emptyx5]
js创建值的两种方式
  • 字面量方式:var obj={}
  • 基于构造函数: var obj2=new Object()
  • 不管是哪种形式创建的,这些对象都是Object的一个实例。
  • 注意:基本数据类型用字面量方式创建的实例,不是标准的实例,用instanceof检测为false,但是可以调用类的方法,如果用构造函数创建类,用instanceof检测为true
  • 注意:引用数据类型,两种方式创建都可以被instanceof检测为true
var n1=1;
var n2=new Number(1);

console.log(typeof n1);//"number"
console.log(typeof n2);//"object"

n1.toFixed(2);//"1.00"

n2.toFixed(2);//"1.00"
原型和原型链
  • 【函数数据类型】
    • 普通函数、构造函数、箭头函数
  • 【对象】
    • 普通的对象、数组、时间对象、正则…
    • prototype/_ _ proto _ _原型属性值也是对象,但不包含(function.prototype)
    • 实例(不包括7种原始数据类型)
      • 如10是Number的实例,但不是一个对象
  • 大部分函数(重点是构造函数)都有一个属性prototype(是原型,也可称为显式原型),他是属性是一个对象数据类型,浏览器会默认给他开辟一个堆内存存的是公有的属性属性和方法,供当前类所属实例调用
  • 箭头函数没有prototype属性
  • prototype天生自带一个属性constructor,指的是当前的构造函数(所属的类)
  • 所有对象都天生自带一个_ _ proto _ _属性,他指向当前实例所属的原型,找到最后时,__ proto__为null

原型链查找:

先看自己私有的有没有,如果没有,基于__proto__向上查找,(简单概括为先找私有,再看公有)如果一直没找到就为undefined

function Fn(){
   var n=100;
   this.A=function(){console.log("私有A")};
   this.B=function(){console.log("私有B")}
}
Fn.prototype.A=function(){console.log("公有A")};
var f1=new Fn();
var f2=new Fn();
console.log(f1.A==f2.A);
console.log(f1.__proto__.A==f2.__proto__.A);
console.log(f1.__proto__.A==Fn.prototype.A)

图解
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值