day13——js基本概念总结及闭包,dom元素及操作

概念补充——基本语法

1. 变量类型(面试题)

在java,php,c#等后端语言中,大概有14种数据类型:

类型定义
int整型(有符号)
uint无符号整型
long长整型
ulong无符号长整型
byte8位,用于表示最小的数据单位,默认为0,范围为-128~+127
sbyte有符号8位
short32位,很少用,范围为-32768~+32767
string字符串
char字符类型,16位
bool布尔型
float32位单精度浮点型,不精确,不能进行精确比较
double64位双精度浮点型
decimal格式: decimal (M,D);M为最大精度位数,D为小数点右侧位数
object对象

而java是一种弱类型语言,所有变量均用var声明;变量数据类型有六种:
number string boolean object null undefined(其中数组,空都属于对象object类型),还有函数类型function
eg:

     var a=10;
     var b="nihao";
     var c=true;
     var d={};//对象
     var e=[];//数组
     var f=null;//空对象引用
     var g=undefined;//未定义
     console.log(typeof a);//number
     console.log(typeof b);//string
     console.log(typeof c);//boolean
     console.log(typeof d);//object
     console.log(typeof e);//object
     console.log(typeof f);//object
     console.log(typeof g);//undefined
     console.log(typeof showname);//function
     function showname(){}

数据类型大体分为两类:值类型和引用类型
值类型 值
引用类型 : function和对象
区别:–值类型是 值的引用空间不变(在内存中的位置不变),引用类型 :引用的位置是可变的

2. 变量在使用之前切记初始化,若使用时未初始化,则数据类型为undefined ,未定义类型,并且有提示信息 error: a is not defined/undefined
3. 变量的提升——变量会被js 提前声明
eg: 
console.log(a);//undefined:
执行完之后检测到a是未定义,说明a只是被声明但未完成初始化
 var a=10;//这里面包含两部分,变量a的声明和初始化赋值
          console.log(a);

函数(除匿名函数外)也会被提前声明 , 如果不被提前声明,在函数定义之前解析到show(),会提示show is not a function;但是浏览器可以执行函数输出结果为1

  show();//function
    function show() {
        console.log(1);
    }
4. 函数
a)带返回值的函数;
function showinfo() {
         //执行代码
         return 1;
    }
    var a = showinfo();
    console.log(a);//1
b)带参函数
function showname(name, sex, age) //括号中为形参{
    return name;
}
var name = showname("张三", "男", 18);//实参
console.log(name);

如果函数没有参数列表 传递参数怎么接收参数?

function showData() {
        //arguments 参数列表对象arguments  
        取值按照集合来取值 ,key:value索引取值:
      console.log(arguments[0], arguments[1], arguments.length);
    }
showData("小花", 18);
c) 匿名函数——不带函数名称的函数 ,用变量去接收 —匿名函数不提前声明
list(); //,匿名函数不会被提前声明,在函数体前面调用函数报错
var list = function () {
    console.log(arguments);
    return arguments[0];
}
console.log(list(1, 2, 3));

在这里插入图片描述

d)自执行函数——自动执行的函数体,有实参形参 返回值

格式:
var 变量=(function(参数){})(参数)//后面这个括号表示执行函数
eg:有参数有返回值

var mm = (function (x, y) {
        console.log(x, y);
        console.log(arguments);
        return x + y;
    })(1, 2);
console.log(mm);

例题:写出输出结果(tips:观察变量颜色)

在这里插入图片描述

解析:因为全局变量和局部变量名称相同
在进入函数体后,由于函数体内部声明了temp同名变量(声明变量和赋值
是两步操作),此时的局部变量temp未初始化会覆盖之前定义的object,
所以检测到temp为undifined输出;在执行完赋值语句输出student,
之后所有的temp变量就又变成了“student”
5.js是面向对象开发,而对象包括属性和行为,世间万物皆对象

变量作用域(全局变量,局部变量),闭包

1. 变量作用域示意图:

在这里插入图片描述

eg1:(同理注意观察变量颜色)
声明变量为全局变量的时候可以不写var
在这里插入图片描述
eg2:
在这里插入图片描述

输出结果为6;
首先定义全局变量为value=3,执行函数test(),结果为return后的函数,
再执行return后的函数且参数为2,且调用了全局变量window.value此时
为3则结果为3*2等于6

js里面定义全局变量 ,全局方法 , 都是window属性 浏览器最大对象

2.闭包

变量里面的闭包 —使用别人的局部变量 ,闭包会大量占用内存 会导致网页内存泄露 ,应尽量避免使用闭包
eg1

 //在f2中调用f1函数
function f1(){
        var a=10;
        return a;
    }
    function f2(){
        console.log(f1());
    }
f2();

例题1:判断输出结果
在这里插入图片描述

    var a1=f1();//括号表示执行函数f1,
    			结果为return 后的内容——一个匿名函数
    a1();//执行return后的匿名函数,结果为1
    t();//执行匿名函数t,此时a为2
    a1();//在执行return后的function输出a
将t声明后执行函数会报错的原因是,不用var声明则为全局变量,可以在外
部调用,用var声明后再调用时会提示变量未定义

例题二:判断输出结果
在这里插入图片描述

console.log(f1()());//第一个括号表示执行函数f1,结果为return后
的内容(function f2),第二个括号表示执行f2函数,返回n的值999

console.log(f1());输出return后的内容即
在这里插入图片描述
例题三:
在这里插入图片描述

fooOuter1();//输出为global
执行footOuter1函数其中name为局部变量,只在该函数内部有效,再闭包
调用函数foo,执行后输出name,全局变量作用于整个代码此时输出global

例题四:(就像局部变量一样,潜逃在一个函数内部的函数为局部函数,局部函数取就近)

在这里插入图片描述

输出结果为local//局部函数就近取值

例题五:
在这里插入图片描述

输出11//第一个括号执行f1函数,结果为return 后的内容,
第二个括号表示执行函数f2,b自增后输出

例题六:方法重写(改写函数内置功能,一般情况下改写toString或valueOf,重写tostring 会自动执行String 类里面的tostring)
在这里插入图片描述

方法重写后,将toString改写成需要的功能:返回m的值,
console.log(f2(1));//输出结果为1

常规语句

1. js里面的运算符 —算数运算符 —逻辑算符 —比较运算符
2. 语句包括 循环语句 条件语句 switch 选择结构 三元运算符
3.

// 简单的for 也称死循环

		for(; ; ){}
4. 简单应用

eg输出下列形状
在这里插入图片描述

for (var i = 0; i < 4; i++) {
        for (var k = 0; k < 7; k++) {
            document.write("*")
        }
        document.write("<br>");}

在这里插入图片描述

    for (var i = 0; i < 4; i++) {
            for (var k = 0; k < 3 - i; k++) {
                document.write("&nbsp;&nbsp;");
            }
            for (var k = 0; k < 7; k++) {
                document.write("*")
            }
            document.write("<br>");
        }

打印菱形

document.write("<div align='center'>");
    var k=prompt("请输入打印行数");
    for(var i = 0; i < k; i++) {
//        上半部分:
        if(i <= Math.floor(k/2)) {
//            打印空格
            for(var j = 1; j <=  Math.floor(k/2) - i; j++) {
                document.write('&nbsp;');
            }
//            打印*
            for(var j = 0; j < i * 2 + 1; j++) {
                document.write('*');
            }
        }
        else {
            for(var j = 1; j <= i -  Math.floor(k/2); j++) {
                document.write('&nbsp;');
            }
            for(var j = (k - i) * 2 - 1; j > 0; j--) {
                document.write('*');
            }
        }
        document.write('<br />');
    }
    document.write("</div>");

打印金字塔形状的九九乘法表

document.write("<div align='center'>");
for(var x=1;x<=9;x++){
 for(var y=1;y<=x;y++){
 document.write(x+"*"+y+"="+x*y);
 }
    document.write("<br>");
 }
document.write("</div>");

dom元素获取

1. dom :document object model (文本对象模型)
2. document dom对象在页面中就是整个页面(html)
3.dom元素的8种获取方式,在进行dom元素获取的时候注意 获取的元素是否初始化
a) document.getElementsByClassName()
b) document.getElementById()
c) document.getElementsByName()
d) document.getElementsByTagName()

前面4个选择 属于动态的获取dom,动态获取:通过js获取
在js里面不能进行隐式迭代 (说人话:不能操作一堆元素 只能操作单个元素)
各个获取方式获取到的内容不同
eg:在这里插入图片描述

1)var b_ele = document.getElementsByClassName("block");
	//获取到的类型为HTMLCollection  标签集合型/数组 
	//取元素对象要按照索引来取值如:b_ele[0].innerHTML = "1111";
2)var a1 = document.getElementById("binfo");获取的为单个对象
3)var a3 = document.getElementsByTagName("div");//获取到的
	  //为HTMLCollection  标签集合型/数组,
	  //同理取元素对象时要通过索引
4)var a2 = document.getElementsByName("blist"); 
 //NodeList节点数组类型,同理要通过索引取对象

以下两个为静态获取,即一开始就写在页面中的,通过选择器来获取元素

document.querySelector();//返回单个元素
document.querySelectorAll();//返回多个元素,一个NodeList集合

e)var a4 = document.querySelector("#binfo");//返回单个元素,即使是多个同名class也只返回第一个class的元素
f)var a5 = document.querySelectorAll("#binfo1");//返回多个元素

特定的元素获取方式

g)  console.log(document.body);  //获取body
h) console.log(document.documentElement);//  获取html 

dom事件的操作

1. 键盘事件 鼠标事件 表单事件 浏览器事件
a)  onkeydown  onkeyup onkeypress
b)  onmouseover,onmousemove,onmouseout(包含垂直离开)
	onmouseleave(水平离开)  onclick  ondblclick(双击执行)  
	onmousedown onmouseup  
	oncontentmenu (右键目录栏,return false取消右键事件)
c) onfocus   onblur   onselected  onchange
d) onload   onreload   onresize(改变尺寸)    onerror
2. 事件在js里面有多少种写法:3种

此处的举例代码前提
在这里插入图片描述

  • 直接在网页上写

    function showname() {
    alert(“张三”);
    }

  • 动态绑定事件

    var btn = document.querySelector("#btn");
        btn.onclick = function () {
        alert("你点我");
            btn.onclick=null;//单击一次后不再出现弹框
        }
   btn.onclick=showalert();//不加括号——否则在点击前就执行了函数
        function showalert(){//想要再重复提示弹框
        alert("你点我");
        }
  • 事件的监听

只有click点击事件才能冒泡,且父元素和子元素都为点击事件
1、如果不解除事件的效果则使用匿名函数,如果需要解除则使用一般函数
不解除:

 var btn = document.querySelector("#btn");
    btn.addEventListener("click", function () {
        alert("1");
});

需要解除:

  var btn = document.querySelector("#btn");
    btn.addEventListener("click",show);//事件不加on
    function show() {
        alert("1");
        this.removeEventListener("click",show);
}
2、不能绑定多个事件,每次只能绑定一个事件
3、addEventListener共有三个参数:event事件,function函数,useCapture指定事件在捕获或冒泡阶段执行,布尔值,true为捕获,false为冒泡,默认为false冒泡

默认冒泡,从内到外执行

var ul = document.getElementsByTagName("ul");
var li = document.getElementsByTagName("li");
ul[0].addEventListener("click", function (e) {
    console.log(1);
});
li[0].addEventListener("click", function (e) {
    console.log(2);
});

结果:
在这里插入图片描述
加上参数true后

var ul = document.getElementsByTagName("ul");
var li = document.getElementsByTagName("li");
ul[0].addEventListener("click", function (e) {
    console.log(1);
},true);
li[0].addEventListener("click", function (e) {
    console.log(2);
},true);

输出为1,2

4、处理事件冒泡,即要阻止事件冒泡,事件的执行参数为e event,写在函数参数中,在原生js里面阻止事件冒泡是 e.stopPropagation();后期框架中为return false;

在子元素中加上 e.stopPropagation();阻止冒泡,输出为2

var ul = document.getElementsByTagName("ul");
var li = document.getElementsByTagName("li");
ul[0].addEventListener("click", function (e) {
    console.log(1);
});
li[0].addEventListener("click", function (e) {
    console.log(2);
    //阻止事件冒泡  
    e.stopPropagation();
});
5、事件的执行参数为e event-有开发者使用的相关属性和方法
  • 1)事件的执行对象直接添加事件匿名函数上面
    document.body.onkeypress=function (e){
        console.log(e);
    }

除了键盘事件外也可以为鼠标事件(以坐标为主),屏幕事件等
在这里插入图片描述
得到键盘键入后的所有对象
便可直接调用

document.body.onkeypress=function (e) {
        //1.事件的执行对象直接添加事件匿名函数上面
        //获取按键键值
        console.log(e.keyCode);
}

输出键入字符的ascii码

  • 2)可以直接声明变量使用window.event 调用事件的执行对象
    document.body.onkeypress=function () {
        var e = window.event;
        console.log(e);
    }

同样可以输出结果
鼠标事件

document.body.onmousemove=function (e){
     console.log(e.pageX, e.pageY);//获取坐标
     }
6、事件的委托 click事件委托
var ul = document.getElementsByTagName("ul")[0];
    var li = document.getElementsByTagName("li")[0];
    ul.onclick = function (e) {
        //输出的当前点击的元素
        //1.找到委托的元素对象
        var child = e.target || e.srcElement;

        console.log(e);
        if (child.nodeName.toLowerCase() == "li") {
        //toLowerCase转化为小写
            console.log(1);
        }
    }

找到ul下的li元素时输出1

7、Js中的this指针
  • 函数里面的this 指代window对象
    function showData() {
        console.log(this);
    }
    showData();

输出为window

  • 事件里面的this指代当前执行事件的对象
    var btn = document.querySelector("#btn");
    btn.onclick = function () {
        console.log(this);
    }

输出为<button id="btn">按钮</button>

  • js中的自定义对象 this 对象
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
闭包是指一个函数访问其词法作用域外部的变量,并且即使这个函数在其定义所在的作用域外被执行,它仍然能够访问和操作这些变量。 js闭包的优点有: 1. 保护变量:闭包可以创建一个私有的作用域,通过将变量隐藏在函数作用域内部,防止变量被外部访问和修改,提高代码的安全性。 2. 延长变量生命周期:闭包可以延长变量的生命周期,即使函数执行完毕之后,闭包内的变量依然会存在,这样可以保留一些需要在后续操作中使用的变量值。 3. 实现模块化:通过闭包可以实现模块化的代码组织方式,将相关的变量和函数封装在一个闭包内部,减少变量的全局污染,提高代码的可维护性和可重用性。 js闭包的缺点有: 1. 内存占用:使用闭包时会导致变量一直存在于内存中,如果闭包持有大量变量或者引用外部大对象,会占用较多的内存空间,增加内存压力。 2. 性能问题:闭包会使函数的作用域链变长,影响函数的性能,访问外部变量时需要经过更多的作用域链查找。在大量使用闭包的情况下,会降低程序的执行效率。 3. 内存泄漏:如果闭包存在循环引用,即闭包内的变量引用了外部作用域的变量,并且外部作用域的变量又引用了闭包内的变量,这样会导致内存无法释放,造成内存泄漏问题。 使用场景: 1. 保护私有变量:当需要保护一些私有的变量不被外部访问和修改时,可以使用闭包将这些变量封装起来。 2. 实现模块化:使用闭包可以封装一些相关的变量和函数,实现模块化的代码组织方式,提高代码的可维护性和可重用性。 3. 延长变量生命周期:当需要在函数执行完毕后依然保存某些变量的值时,可以使用闭包将这些变量封装起来,延长它们的生命周期。 4. 回调函数:在事件处理、异步编程等场景中,经常需要使用闭包作为回调函数,可以访问到外部的变量和状态。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值