函数和原型
1、每一个函数(类)都有一个属性prototype原型
js是一门基于原型的语言,通过函数模拟类
给实例共享公共方法
{}可以创建对象,new Object()也可以创建对象,所有{}可以看作是new Object出来的
实例对象查找属性、方法,如果自身没有,或通过原型类的形式查找
对象和隐私模型
每一个实例对象都有一个隐私原型proto;指向创建该对象的原型
let f = new Array();
console.log(f.__proto__==Array.prototype);//ture
函数和构造器:类的原型上constructor,指向函数本身
function foo(){
}
console.log(foo.prototype.constructor==foo);//ture
原型链
链:链式调用、作用域链、原型链
实例对象在属性、方法查找顺序:实例对象自身找----》创造这个实例对象的类的原型上找----》Objict原型----》null
instanceof 判断一个实例是否属于某个类 obj instanceof class
function Dog(){
}
let obj = new Dog();
console.log(obj instanceof Dog ) ture
继承
1、何时发生继承:类与类之间发生关系 存在 is 关系
2、继承能做什么:自动继承父类的所有属性和方法(方法是特殊的属性 key 对应的value是一个function)
3、继承能解决什么:代码复用
4、糟糕继承只能把关系搞得更复杂,代码冗(rong)余
extends继承 继承的属性就不用再写一遍,并且super必须出现在 constructor的第一行
class Animal{
constructor(name,age,dengder,color){
this.name = name;
this.age = age;
this.dengder = dengder;
this.color = color;
}
}
class Dog extends Animal{ //extends继承
constructor(name,age,dengder,color,gf){
super(name,age,dengder,color); //继承的属性就不用再写一遍,并且super必须出现在 constructor的第一行
this.gf = gf
}
}
let xiaohei = new Dog("xiaohei",2,"male","white","小黑的女朋友")
console.log(xiaohei); //Dog {name: "xiaohei", age: 2, dengder: "male", color: "white", gf: "小黑的女朋友"}
this指向
1、全局的一个环境下----》window node(终端)环境中-----》global
2、普通函数this -----》window 普通的函数嵌套也是指向window
function fn(){
console.log(this)//window
}
3、通过对象调用函数,改函数的this指向该对象
let obj = {
name:"name",
talk(){
console.log(this)//obj这个对象
}
}
实例二
function fn(){
console.log(this)//window
}
let obj = {
name:‘name‘,
}
obj.talk = fn;
obj.talk()//还是该对象
4、事件源-----》事件源
ul.onclick=function(event){
console.log(this)//事件源
console.log(event.target)//触发事件的某元素
}
5、构造函数-----》new 出来的那个实例
6、箭头函数 没有自己this,所处的环境中的this||继承环境中的this||this指向取决于当前声明的环境
3种环境:全局、函数环境、eval 箭头函数没有自己的this。对象无法生成上下文,所以只有全局上下文,所以箭头函数使用全局的this
let obj = {
name:‘lisi‘,
talk:()=>{
console.log(this) //window
}
}
var声明的变量===window
var a = 5;
console.log(windown.a===a)
更改this的指向
1、call 呼叫
2、apply 申请 同意 应用
3、bind 捆绑
语法: fn.call(target) apply.call(target) bind.call(target) () bind 更改 后返回函数,根据需求再调用
function foo(){
console.log(this)
}
let obj = {
name:"zhangsan"
}
foo.call(obj);
foo.apply(obj)
foo.bind(obj)();
传参 fn.call(target,5) fn..apply.(target,[5]) fn.bind(target) (5)
function foo(a){
console.log(this,a)
}
let obj = {
name:"zhangsan"
}
foo.call(obj,5);
foo.apply(obj,[5]);
foo.bind(obj)(5)
作用域 scope
作用:有功能、区域
域:区域、范围
变量、函数生效的范围
作用域产生的时间
函数【声明】时产生
作用域的分类
全局、局部(函数跟块)、eval
执行上下文 EC(execution context)
环境,代码执行环境
EC产生的时间
窗口打开全局、函数调用时候产生、
生命周期
全局:窗口的打开---窗口的关闭
局部:调用----调用完毕
js 是单线程非阻塞式语言,一次只能执行一件事,每次新建的EC会被添加到栈顶,浏览器总是运行位于栈顶的EC,完成后退栈,又将控制权交还给当前EC
EC组成
1、EC创建 2、EC激活阶段 3、EC销毁阶段
ES3 ES5
ES3:
1、VO(AO)
1.1arguments
1.2声明式函数 function XX(){}
1.3 var 声明的变量
2、scope
3、this
ES5:
1、词法环境
1.1环境记录----》记录 let const class
1.2对外引用---》ES3 scope
2、变量环境 延续ES3
作用域链
查找变量:先找自身,找不到,则去声明出找
let n = "sdas"
function f(){
console.log(`${n}`); //sdas
}
function foo(){
var n = "123";
f()
}
foo()
?
?
?
var n = "sdas"
function f(){
console.log(`${n}`); //123
}
function foo(){
var n = "123";
f()
}
foo()
作用域链:找变量 scope chain(SC)
原型链:找属性和方法
垃圾回收
计算机:无用的数据
垃圾回收的目的:清内存
function foo(){
let i = ;
}
foo();
console.log(i)//调用完成,出栈,无人使用,销毁
?
const = arr[1,2,3]
arr = null;//切断了引用,无人使用,就是垃圾了,所有123就被浏览器当垃圾回收了
闭包 closure(封闭)
MDN:有函数、就有闭包
闭包的组成:函数+周围的环境
function outer(){
let a = 5;
return function(){
console.log(a)
}
}
let result = outer();
result();
?
?
并不是所有的闭包用return;
function outer(){
let a = 5;
window.inner = function(){
console.log(a)
}
}
result();
inner();
广义:有函数就有闭包
狭义:函数调用完成后,该被销毁的,由于应用,导致没有销毁
递归
let j = 0;
function foo(){
j++;
console.log(j); //12345
if(j==5){
return
}
?
foo();
}
foo()
attribute property 都是属性的意思
attribute :html标签属性 <div id = "box"></div> 值都是String类型
property :js对象属性
常见的属性:id class name value attribute 同property的操作
property操作
Object.getOwnPropertyDescriptor() 获取属性描述符
const zhangsan = {
name:"zhangsan"
}
let result = Object.getOwnPropertyDescriptor(zhangsan,"name")
console.log(result); //{value: "zhangsan", //记录属性值
writable: true,// 是否可以被修改
enumerable: true, //是否可枚举 configurable: true //是否可以被配置(删除)}
被添加的属性默认是不可修改的、删除的、被遍历到 Object.defineProperty(obj,"pro",descriptor)
obj.pro = newValue;
delete obj.pro 无法删除;
for in 无法遍历到
const zhangsan = {
name:"zhangsan"
}
Object.defineProperty(zhangsan,"age",{
value:18,
})
要想可修改的、删除的、被遍历到
const zhangsan = {
name:"zhangsan"
}
Object.defineProperty(zhangsan,"age",{
value:18,
writable:true,
enumerable:true,
configurable:true
})
value、writable不能和get和set共存
const zhangsan = {
name:"zhangsan"
}
Object.defineProperty(zhangsan,"age",{
enumerable:true,
configurable:true,
get(){
},
set(){
}
})
get 访问obj.pro自动的调用
set 设置obj.pro自动的调用
const zhangsan = {
name:"zhangsan"
}
Object.defineProperty(zhangsan,"age",{
enumerable:true,
configurable:true,
set(){
console.log(666);
},
get(){
}
})
作用
比例原生对象某些属性、方法、只能获取不能设置(鼠标的坐标、某个键是否被按下)
属性不能被删除(arr.length)
const zhangsan = {
name:"zhangsan",
_age:18
}
Object.defineProperty(zhangsan,"age",{
set(v){
if(v<0||V>100){
return this._age
}else{
this._age = v;
}
},
get(){
return this._age
}
})
SVG概述:Scalable Vector Graphics可伸缩的矢量图形
本地存储
三种方式:
cookie -----》93年的 有弊端 只有4kb
html5:localStorage sessionStorage
local:本地 永久存储 除非人为删除
session :会话 窗口关闭,就删除
跨窗口localStorage 可以相互访问
1、查看长度localStorage.length
console.log(localStorage.length);
2、添加 localStorage.属性 = ""; || localStorage.setItem("key","value")
localStorage.textName = "zhangsan";
3、访问 localStorage.key||localStorage.getItem("key")
4、删除 delete localStorage.属性|| localStorage.removeTtem("属性")
5、清空 localStorage.clear();