This commit is contained in:
asd
2021-06-03 10:52:41 +08:00
parent c5f18c6051
commit 907511778b
54 changed files with 3540 additions and 50 deletions

View File

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var y=2
function fn(){
var x=1
// console.log(x+y) //3
function fn1(){
x=x+32
console.log(x+y)
}
return fn1
}
function m(){
var p=0
console.log(y)
return y
}
var z=fn()
z()
var w=m() //w=undefined
console.log(fn())
// var z=fn()
// console.log(z.toString())
// z() //从全局访问函数fn中的变量 x =====> 闭包
// 闭包: 有权访问另一个函数作用域中变量的函数
// 闭包形式:函数嵌套函数 并且返回内层的函数体
// 闭包作用1. 可以读取函数内部的变量
// 2.让这些变量的值始终保持在内存中
// 造成的问题 1.由于闭包会使得函数中的变量都被保存在内存中内存消耗很大所以不能滥用闭包否则会造成网页的性能问题在IE中可能导致内存泄露。解决方法是在退出函数之前将不使用的局部变量全部删除。
// 2. 不要随便改变父函数内部变量的值。(闭包会在父函数外部改变父函数内部变量的值。所以如果你把父函数当作对象object使用把闭包当作它的公用方法Public Method把内部变量当作它的私有属性private value)
</script>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=\, initial-scale=1.0">
<title>Document</title>
<script>
//递归 : 函数中 自己调用自己
function jiecheng(n){
var jieguo=1
for(var i=n;i>0;i--){
jieguo=jieguo*i
}
return jieguo
}
// console.log(jiecheng(5))
// 阶乘 5 =〉5*4*3*2*1
function jc(m){
if(m<=1){
return 1
}else{
return m*jc(m-1)
}
}
// function jc1(m){
// if(m<=1){
// return 1
// }else{
// return m*jc(m-1)
// }
// }
// 5*jc(4)
// 4*jc(3)
// 3*jc(2)
// 2*jc(1)
// 2*1
// console.log(jc(5))
var jc1=jc
jc=null;
console.log(jc1(5))
</script>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p id="greet1" class="greet">hello world</p>
<p id="greet2" class="greet">hello world
<span id="yu">asd</span>
</p>
<div id="draw"></div>
<script>
// // 获取元素
// var greet= document.getElementById("greet1") //id
// var greet1=document.getElementsByClassName("greet")
// // var gre=document.getElementsByName("xxx")
// // var gre1=document.getElementsByTagName 标签
// // 除了id之外的获取方式 其他的获取结果都是数组 id的获取方式是单个元素
// console.log(greet1)
// // div.parentsibling
//创建节点
var squeare=document.createElement("div");
squeare.innerHTML="我是div"
squeare.style.color="red"
squeare.setAttribute("name","mydiv") //setattribute 设置属性 第一个参数是属性名 第二个参数是属性值
var draw=document.getElementById("draw")
draw.append(squeare)
console.log(squeare)
var greet2=document.getElementById("greet2")
var span=document.getElementById("yu")
greet2.remove(yu)
// greet2.removeChild(yu) //删除子元素
</script>
</body>
</html>

View File

@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<input type="text" id="name" value="">
<button onclick="add()">添加</button>
<table id="biao">
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>操作</th>
</tr>
</table>
<script>
var table1 = document.getElementById("biao");
var info = [{ name: "张三", sex: 1, age: 23 }, { name: "刘亦菲", sex: 2, age: 38 }, { name: "蔡徐坤", sex: 1, age: 24 }]
function show() {
console.log(info.length)
var len=info.length
for (let i = 0; i < info.length; i++) {
var tr = document.createElement("tr");
tr.innerHTML = "<td>" + info[i].name + "</td><td>" + info[i].sex + "</td><td>" + info[i].age + "</td><td><button onclick='del("+i+")'>删除</button></td>";
table1.append(tr)
}
// for (let i = 0; i < info.length; i++) {
// var tr = document.createElement("tr");
// tr.innerHTML = "<td>" + info[len-1].name + "</td><td>" + info[len-1].sex + "</td><td>" + info[len-1].age + "</td><td><button onclick='del("+(len-1)+")'>删除</button></td>";
// table1.append(tr)
// }
}
show()
function add() {
table1.innerHTML="<tr><th>姓名</th><th>性别</th><th>年龄</th><th>操作</th></tr>"
var name=document.getElementById("name").value;
console.log(name)
info.push({name:name,sex:2,age:18})
show()
}
function del(e){
console.log(e)
table1.innerHTML="<tr><th>姓名</th><th>性别</th><th>年龄</th><th>操作</th></tr>"
info.splice(e+1,1)
// e+1
show()
}
</script>
</body>
</html>

View File

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.btn{
background:blue
}
</style>
</head>
<body>
<button>点我弹窗</button>
<script>
// 绑定事件的方式
// 1. 在html元素里面直接注册事件 <button onclick="tijiao()">提交</button>
// 2. 从js script标签里面 先选中目标元素 然后通过选中元素.事件注册 来完成注册事件:
// btn[0].ondblclick=function (){
// alert("asd")
// }
// 3. 从js script标签里面 先选中目标元素 然后通过选中元素.事件注册 在注册事件的时候直接使用 addeventlistener
window.onload=function(){
console.log("我再加载")
}
var btn=document.getElementsByTagName("button")
// btn[0].ondblclick=function (){
// alert("asd")
// }
btn[0].addEventListener("click",tanchu)
btn[0].style.width="200px"
console.log(btn[0].style.width)
btn[0].className="btn"
console.log(btn[0].style.background)
function tanchu(){
// alert("asd")
console.log(event)
}
// keypress 长按 键盘事件
</script>
</body>
</html>

View File

@@ -0,0 +1,133 @@
## 闭包的引入
我们知道,变量根据作用域的不同分为两种:全局变量和局部变量。
- 函数内部可以访问全局变量和局部变量。
- 函数外部只能访问全局变量,不能访问局部变量。
- 当函数执行完毕,本作用域内的局部变量会销毁。
比如下面这样的代码:
```js
function foo() {
let a = 1;
}
foo();
console.log(a); // 打印报错Uncaught ReferenceError: a is not defined
```
上方代码中,由于变量 `a` 是函数内的局部变量,所以外部无法访问。
但是,在有些场景下,我们就是想要在函数外部访问函数内的局部变量,那要怎么办呢?这就需要引入闭包的概念。
## 闭包的概念和代码举例
### 闭包的概念
**闭包**closure指有权**访问**另一个函数作用域中**变量**的**函数**。
上面这个概念出自《JavaScript 高级程序设计(第 3 版)》这本书。上面的概念中指出,闭包是一种函数;当然,你可以**把闭包理解成是一种现象**。具体解释如下。
简单理解就是:如果**这个作用域可以访问另外一个函数内部的局部变量**,那就产生了闭包(此时,你可以把闭包理解成是一种现象);而另外那个作用域所在的函数称之为**闭包函数**。注意,这里强调的是访问**局部变量**哦。
### 闭包代码举例
代码举例:
```js
function fn1() {
let a = 10;
function fn2() {
console.log(a);
}
fn2();
}
fn1();
```
打印结果:
```
10
```
上方代码中,函数 fn2 的作用域 访问了 fn1 中的局部变量,那么,此时在 fn1 中就产生了闭包fn1 称之为闭包函数。
### 在 chrome 浏览器控制台中,调试闭包
上面的代码中,要怎么验证,确实产生了闭包呢?我们可以在 chrome 浏览器的控制台中设置断点,当代码执行到 `console.log(a)`这一行的时候,如下图所示:
![](http://img.smyhvae.com/20200703_2055.png)
上图中, Local 指的是局部作用域Global 指的是 全局作用域;而 Closure 则是**闭包**fn1 是一个闭包函数。
## 闭包的作用:可以读取函数内部的变量
我们来看看下面这段闭包的代码:
```js
function fn1() {
let a = 20;
function fn2() {
console.log(a);
}
return fn2;
}
const foo = fn1(); // 执行 fn1() 之后会得到一个返回值。foo 代表的就是 fn2 函数
foo();
```
上方代码中foo 代表的就是整个 fn2 函数。当执行了 `foo()` 语句之后(相当于执行了 fn1 函数内就产生了闭包。
一般来说,在 fn1 函数执行完毕后,它里面的变量 a 会立即销毁。但此时由于产生了闭包,所以 **fn1 函数中的变量 a 不会立即销毁,因为 fn2 函数还要继续调用变量 a**。只有等所有函数把变量 a 调用完了,变量 a 才会销毁。
而且,可以看出, 在执行 `foo()`语句之后,竟然能够打印出 `20`,这就完美通过闭包实现了:全局作用局成功访问到了局部作用域中的变量 a。
因此,我们可以看出,闭包的主要作用就是:延伸了变量的作用范围。
上面的代码也可以简写成:
```js
function fn1() {
let a = 20;
return function () {
console.log(a);
};
}
const foo = fn1(); // 执行 fn1() 之后,会得到一个返回值。这个返回值是函数
foo();
```
## 闭包的作用:让这些变量的值始终保持在内存中,不会在函数调用后被自动清除。
```
function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000
```
解释:
> 在这段代码中result实际上就是闭包f2函数。它一共运行了两次第一次的值是999第二次的值是1000。这证明了函数f1中的局部变量n一直保存在内存中并没有在f1调用后被自动清除。
> 为什么会这样呢原因就在于f1是f2的父函数而f2被赋给了一个全局变量这导致f2始终在内存中而f2的存在依赖于f1因此f1也始终在内存中不会在调用结束后被垃圾回收机制garbage collection回收。

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,74 @@
# 原型链和原型继承
在学习原型和原型链之前 我们先来复习一下 通过构造函数来创建对象的方式
### 构造函数
任何函数都可以做为构造函数使用
构造函数和普通函数的区别主要在于 调用的时候的差异
普通函数:
```
function create(){
this.role="admin"
}
create()
```
构造函数:
```
function create(){
this.role="admin"
}
var juese=new create()
```
此处的new 也属于运算符的一种 作用是创建一个用户定义的对象类型或具有构造函数的内置对象的实例
* new 操作符的过程
new 关键字会进行如下的操作:
1. 创建一个空的简单JavaScript对象即{}
2.链接该对象设置该对象的constructor到另一个对象
3. 将步骤1新创建的对象作为this的上下文
4. 如果该函数没有返回对象则返回this。
* 分析 ```new foo() ``` 的执行过程
1. 一个继承自 Foo.prototype 的新对象被创建。
2. 使用指定的参数调用构造函数 Foo并将 this 绑定到新创建的对象。new Foo 等同于 new Foo()也就是没有指定参数列表Foo 不带任何参数调用的情况。
3.由构造函数返回的对象就是 new 表达式的结果。如果构造函数没有显式返回一个对象则使用步骤1创建的对象。一般情况下构造函数不返回值但是用户可以选择主动返回对象来覆盖正常的对象创建步骤
接下来我们把上面创建的对象打印一下看看会出现什么结果
![image-20210513165237126](E:\web\lessons\课件\teaching\lhj\kejian\js\note\原型链.assets\image-20210513165237126.png)
然后我们会发现在我们定义的role属性下面多了一个```__proto__``` 属性 这个```__proto__```属性指的就是我们当前对象的原型
### 原型对象
无论什么时候只要创建一个新函数就会根据一组特定的规则为该函数创建一个prototype属性这个属性指向函数的原型对象。普通对象没有 prototype但有``` __proto__``` 属性。
```
function Person() {
}
Person.prototype.name = 'Perty';
var person = new Person();
person.name = 'Kevin';
console.log(person.name) // Kevin
delete person.name
console.log(person.name) // Perty
```

View File

@@ -48,14 +48,13 @@
// 对象 键值对(无序) 数组(有序)
// name sex age 这种类似于变量的东西叫属性
// sayzao saywan这种对象中的函数 叫方法
// 添加属性
var obj={
name:"qwe",
sex:"男",
age:22,
sayzao:function(){
alert("早安")
},
saywan:function(){
alert("晚安")
@@ -65,47 +64,10 @@
// obj.sayzao()
// sayzao()
// 新增属性 obj对象的名字.属性名=属性值
// 新增方法 obj(对象名).方法名=匿名函数
console.log(obj.name)
obj.height=185;
obj.face="好看"
obj.zhuangkuang="单身"
obj.xiaozhushou=function(){
alert("多喝岩浆")
}
obj.cooking=function(time){
if(time==7){
alert("我正在做早饭");
}else if(time==11){
alert("我正在做午饭")
}else if(time==18){
alert("我在做晚饭")
}
}
obj.clean=function(){
alert("我在打扫卫生")
}
obj.wash=function(){
alert("我在把衣服扔到洗衣机里")
}
obj.changename=function(){
this.name="张三"
}
// obj.cooking(7)
// obj.sayzao()
// obj.clean()
// obj.xiaozhushou()
// obj.cooking(11)
// obj.wash()
// obj.cooking(18)
delete obj.saywan
console.log(obj)
</script>
</body>

View File

@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// "use strict";
// this
// 1. 谁调用 就指向谁 指向目标是一个对象
// 2. 如果没有对象调用他 就指向全局对象window
var a=1
// var name;
// console.log(a)
// console.log(window.a)
// console.log(this.a) //1
// var name="华晨宇"
var obj={
name:"asd",
echoname:function(){
console.log(this.name)
}
}
// obj.echoname()
function a(){
var user = "追梦子";
console.log(this.user);
console.log(this); // window
}
// a();
function myFunction() {
"use strict";
console.log(this);
}
// myFunction()
// function fnza(){
// console.log(this.name)
// }
// fnza()
// fnza.name="asd"
// window.name="qwe"
// console.log(fnza.name)
function foo() {
console.log( this.a ,"jkjkjkjkjk");
}
var obj = {
a: 2,
foo: foo
};
var a = "xxxxx"
setTimeout( obj.foo ,100);
</script>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 构造函数
function create(){
this.role="admin"
}
// create()
var obj= new create()
// new 关键字的操作过程:
// 1. 创建一个空对象
// 2. 构造函数中的this指向这个 空对象
// 3. 执行构造函数中的代码 给新对象添加属性和方法
// 4. 返回这个新对象
// 只要是个函数 都有prototype 属性
// 只要是个对象 都有__proto__ 属性(左右两边都是两个下划线)
// 这两个访问的都是对象的原型
// animal cat
function animal(){
this.run=function(){
console.log("我跑得起来")
}
}
var all=new animal()
function cat(kind,hasmao,food){
this.kind=kind;
this.hasmao=hasmao;
this.food=food;
this.jiao=function(sheng){
console.log(sheng)
}
}
var miao=new cat("哺乳类",1,"鱼")
cat.prototype=all
miao.run()
// 顺序
// 先写父级的构造函数
// 创建父级对象
// 写子级的构造函数
// 指定子级的原型
// 创建子级对象
</script>
</head>
<body>
</body>
</html>

105
teaching/lhj/kejian/this.md Normal file
View File

@@ -0,0 +1,105 @@
# this
 首先必须要说的是this的指向在函数定义的时候是确定不了的只有函数执行的时候才能确定this到底指向谁实际上** this的最终指向的是那个调用它的对象 **
例1
```
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this);  //Window
}
window.a();
//判断this跟this所处的函数没有关系结果取决于哪个对象调用的他 最外层的对象是window
```
例2
```
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
o.fn();
// fn外部是对象O访问的是this.user 即o.user => o.user的值是“追梦子”
```
例3
```
var user="pplok
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
window.o.fn();
```
例4
```
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();
```
总结:
情况1如果一个函数中有this但是它没有被上一级的对象所调用那么this指向的就是window这里需要说明的是在js的严格版中this指向的不是window但是我们这里不探讨严格版的问题你想了解可以自行上网查找。
  情况2如果一个函数中有this这个函数有被上一级的对象所调用那么this指向的就是上一级的对象。
  情况3如果一个函数中有this这个函数中包含多个对象尽管这个函数是被最外层的对象所调用this指向的也只是它上一级的对象
例5
```
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); // undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();
```
判断this时需要看函数调用的位置而不是我们定义函数的位置
this永远指向的是最后调用它的对象也就是看它执行的时候是谁调用的
this 遇到return 时
```
function fn()
{
this.user = '追梦子';
return
}
var a = new fn;
console.log(a.user); //undefined
```
函数return的值为对象时this就指向 这个被return的对象