js高级相关

-------------------------------------------
原型
1.构造函数被创建, 系统都会为之创建一个对象,这个对象就是原型.

函数声明都在内存堆中找一个地方来保存函数的函数体
变量声明都在内存栈中找一个地方

new 关键字做了哪些事情?
1.创建一个对象(对象里有啥就看构造函数里this有啥)
2.把构造函数中this指向这个创建的对象
3.返回创建的对象


把方法写到构造函数中会造成空间浪费


把方法提炼到构造函数外
解决了内存空间浪费的问题
但是存在全局变量污染的问题(比如Student有个test方法  Teacher也有个test方法)


使用一个对象包裹方法
在构造函数中指向对象的方法
解决了内存空间浪费的问题
解决了全局变量污染的问题


原型自己可以访问原型的属性
原型对象对应的构造函数实例化出来的对象们

// __proto__ 隐式原型
// .prototype 显示原型
原型链可以看这里
https://baijiahao.baidu.com/s?id=1685587405779644513&wfr=spider&for=pc  
    // 以下全true
     console.log(s.constructor === Student);  (s没有constructor 去原型链中寻找 即Student.prototype中寻找)
     console.log(s.__proto__ === Student.prototype);
     console.log(Student.prototype.constructor === Student);    

    console.log(Student.__proto__ === Function.prototype)
    console.log(Object.__proto__ === Function.prototype);
    console.log(Function.__proto__ === Function.prototype);

    console.log(s.__proto__.__proto__ === Object.prototype);
    console.log(Student.prototype.__proto__ === Object.prototype)
    console.log(Function.prototype.__proto__ === Object.prototype);
    console.log(Object.prototype.__proto__ === null);

    console.log(Function.prototype.constructor === Function);
    console.log(Object.prototype.constructor === Object);

什么是原型对象
不管什么构造函数被创建,系统都会为之创建一个对应的对象,这个对象叫原型
//使用原型需要注意的地方. 
//1.哪些(什么样的)数据应该往原型中添加?
//原型对应的构造函数实例化出来的对象们 公共的属性/方法.
//2.对象访问成员(属性/方法)的规则:
//对象如果自己有这个属性/方法,那就访问对象自己的; 对象自己没有才访问原型的.(链式调用)
//3.想要修改原型对象上的方法需要修改构造函数.prototype.方法 = fuction(){}
4.原型可以替换
想要修改原型对象上的方法需要修改构造函数.prototype={}

__proto__
1.__proto__已废弃  主要用于验证/学习 prototype

constructor

面向对象语言的三大特征
继承
封装
多态

继承的方式
1.混入式
for in的方式遍历要继承的对象 将之属性加到自己上
let wangjianlin = {
      house: {
        address: '北京',
        price: 10000000
      },
      car: {
        name: '幻影',
        price: 20000
      }
    }

    let wangsicong = {
      girlfriends: {
        name: ['a', 'b', 'c']
      }
    }
    for (key in wangjianlin) {
      wangsicong[key] = wangjianlin[key]
    }

    console.log(wangsicong);

2.替换原型式(缺点会覆盖自己原来的原型)

3.混合式

静态成员和实例成员
静态成员: 构造函数点出来的
实例成员: 实例化对象点出来的
静态成员就是 构造函数.属性
实例成员就是 实例.属性

new的过程(需要看这里 涉及到了call arguments __proto__ prototype  shift)
MDN call  applay也有
https://blog.csdn.net/qq_44606064/article/details/116585653
1.创建一个空对象
2.将构造函数的this指向这个对象
3.返回这个对象

Object静态方法values  可以替代 for in
Object.values(obj)
Object.keys(obj)
-------------------------------------------
原型链
每一个对象都有原型 原型也是对象
所以原型也有原型,这样就形成了一个链式结构,称为原型链

原型链的作用  原型链继承   
对象自己有就访问自己的,对象没有访问原型的,
如果对象也没有就沿着原型链一直往上找,
如果最后还没找 属性为undefined 方法报错not a function

内置对象的原型链
let arr = new Array()
arr.__proto__ === Array.prototype
Array.prototype.__proto__ === Object.prototype
Object.toString() 得到 [object type]type是调用者的类型
arr.toString()和Object.toString()不一样 因为Array重写了toString()方法

let date = new Date()
date .__proto__ === Date.prototype
Date.prototype.__proto__ === Object.prototype
date.toString()和Object.toString()不一样 因为Date也重写了toString()方法

console.log(date)默认调用date.toString()
console.dir(date)打印date本身

DOM对象的原型链
.__proto__
div HTMLDivElement HTMLElement Element Node EventTarget Object null
p HTMLParagraphElement HTMLElement Element Node EventTarget Object null
a HTMLAnchorElement HTMLElement Element Node EventTarget Object null
document Document Node EventTarget Object null

构造函数和函数都是一个对象
都可以看成对象,都是Function实例化出来的

构造函数和普通函数 本质上没有的区别 
只有人为的区别
a.构造函数名是一个名词,普通函数一般是一个动词
b.构造函数名首字母一般大写
c.构造函数体里面一般有this.xx
构造函数一般配合new关键字使用
this.xx=xx是给new关键字创建出来的对象赋值

完整的原型链
constructor
prototype
__poroto__
实例化

instanceof
语法:对象 instanceof 构造函数
作用:判断这个构造函数的prototype属性在不在这个对象的原型链上
实际作用:
a.判断这个对象是那个构造函数的实例(判断类型)
b.可以放心的让这个对象去调用构造函数的prototype里面的成员

arguments 伪数组 实际是一个Object
1.只能在函数体内部使用
2.它是伪数组(有length,下标),本质是一个对象
3.里面存放的是实参的值
4.和形参一一对应 修改arguments也会修改形参的值

剩余参数 语法就是...
function test(num, ...arr){}

test(10,20,30,40)

默认参数 不传参的时候生效
function test(num1=10, num2=20){
return num1 + num2
}
test()
test(20,30)

-------------------------------------------

函数this的指向
不要去管这个函数在哪里如何声明的,就看谁调用这个函数那这个函数中的this就是谁

1.作为普通方法调用
window
2.作为方法调用
谁调用指向谁  比如test() === window.test()   指向window
obj.test() 指向obj
3.作为构造函数调用
配合new创建对象,this就是new关键字创建出来的那个对象

函数上下文调用模式
1. 普通函数执行 方法执行 构造函数执行
this无法更改 报错(赋值运算符左值无效)
非要改的话用call bind apply

call调用函数  
可以用于伪数组转真数组  
函数名.call(this新指向,原来函数的参数1,原来函数的参数2) 原来函数有几个就写几个参数 返回新数组
es6有更简洁的方法 伪数组转真数组 Array.from()

万能数据检测
Object.prototype.toString.call(null)
Object.prototype.toString返回一个“[Object type]”的字符串   type是对象的类型

apply调用函数 第一个参数this指向 第二个参数数组或者伪数组
getsum.apply(obj,[100,200])将数组中的元素依次传给getsum()的形参
伪数组转真数组
求数组最大值 es6展开运算符 ...

bind调用函数
函数名,bind(this的新指向,可选参数)  可选参数就是可写可不写
不会执行函数,返回一个改了this但是函数体不变的函数
修改定时器
定时器中的this默认是window

call bind apply定义在哪里
Function.prototype
test().call(123)           Number
test().call(NAN)         Number
test().call('abc')          String
test().call(true)          Boolean
test().call(null)            window
test().call(undefined) window

借用构造函数继承.
使用call bind apply都可以

组合继承(借用构造函数继承+替换原型继承)
注意替换原型继承时 使用 new father()这样可以避免父亲new的实例也拥有son的方法

闭包
声明在函数内部,可以访问函数内部的局部变量的这么一个函数. 

闭包的作用01: 提升变量的生命周期.(本来要回收的现在不让你回收)
1.变量的生命周期: 就是从变量声明出来开始,到变量被回收.
1.1 局部变量的生命周期:从声明他的那句开始到声明他的函数执行完毕结束
1.2 全局变量的生命周期:从声明他的那句话开始,到程序结束(页面关闭)
闭包的作用02: 提供有限的访问权限
闭包的作用03: 构造函数声明私有属性

使用闭包需要注意的地方

沙箱/沙盒
a.避免全局变量污染
b.模块化开发

什么是闭包

闭包就是 
函数内访问局部变量的函数
申明在函数内部 可以访问函数内部的局部变量的一个函数

闭包就是
声明在函数内部 可以在函数内部访问局部变量的一个函数
申明在函数内部 可以在函数内部访问局部变量的一个函数

-------------------------------------------
块级作用域 
一个{}括起来的就是块级作用域

ES6语法
var和let与const
1.var关键字:es6之前声明变量都用var
a.有变量提升(会把变量的声明提前到 当前作用域 最顶端,赋值语句保留在原地)
b.没有块级作用域,有函数作用域
c.可以重复声明
d.可以重复赋值

2.let关键字:es6之后声明变量可以用let
a.没有变量提升
b.有块级作用域
c.不能重复声明
d.可以重新赋值

3.const关键字:声明常量用const
a.没有变量提升
b.有块级作用域
c.不能重复声明
d.不能重新赋值
e.声明的时候一定要初始化

解构赋值
对象解构赋值
如果对象的属性名和声明的变量名一致,那就可以简写
对象没有对应的属性时 为undefined
新声明一个属性从左往右赋值
可以赋默认值
如果设置了默认值  但是变量obj也有 默认值会被覆盖
{name = 19} = obj
let name = 19
name = obj.name

数组解构和对象解构差不多

函数的形参是对象的话 
在函数体内部也可以解构
在函数形参部分也可以解构

箭头函数:就是匿名函数的简写
简写规则:
a.把function 改成 =>
b.如果形参只有一个 可以省略()
c.如果形参不是一个(0个或多个) 不能省()
d.函数体只有一句话可以省略{}
e.函数体只有一句话可以return
f.函数体不是一句话可以省略{}不能省略

箭头函数this的指向 是声明它的环境的this
原理就是_this = this 把声明它的环境的this保存下来

不能用new调用箭头函数

对象成员(属性、方法)简写
声明一个对象,他的属性值是已经声明的变量的值
let name = 1
let obj = {name}   ===   let obj = {name:name}
let obj = { sayHi:function(){} } === let obj = { sayHi(){} }

展开运算符 ...  对象展开 数组展开
数组展开
拼接数组

数据类型Set
元素不可以重复 可用于数组去重
arr = [...new Set(arr)]

创建类class

es6中的class 本质上就是es5中的构造函数
写在class中的方法 本质就是es5中构造函数.prototype的方法

继承关键字extends 本质是原型链继承
super本质是父类.call(this,参数)
super.方法调用父类方法

数组方法
arr.forEach 遍历不会停下来 无法break 和 continue 没有返回值
map  遍历不会停下来 按照某种映射关系 把数组的每一个元素给修改 返回一个数组 新数组的元素是 return的元素
filter 遍历不会停下来 返回一个新数组 新数组的元素是  条件成立的当前item项
find 查找符合条件的第一个元素,找到就返回这个元素,没有就返回undefined 找到后就退出循环
findIndex 查找符合条件的第一个元素,找到就返回这个元素下标,没有就返回-1 找到后就退出循环

innerHTML - 节点(元素)的文本值
parentNode - 节点(元素)的父节点
childNodes - 节点(元素)的子节点
attributes - 节点(元素)的属性节点

querySelector
querySelectorAll

getElementById
getElementByTagName
getElementByClassName

appendChild
removeChild
replaceChild
insertBefore

createAttribute
createElement
createTextNode

getAttribute
setAttribute


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值