JavaScript基础
1.什么情况下是undifind:变量声明了,但是没有定义. 如果一个undifind的数和一个数字进行计算,结果是:NaN,即not a number,不是一个数字,也没有什么意义.
isNaN() // 意思是:括号中的数字 是不是 不是 一个数字 ?
isNaN(10) // 结果:false
2.如何获取一个变量的数据类型?
(1) 使用typeof 获取变量的类型:
1.typeof 变量名
2.typeof(变量名)
var numb=10;
console.log(typeof numb); // number
(2) js中的进制!
var num=10; // 十进制
var num=012; //八进制
var num=0X123 //十六进制
(3) 数字范围类型有范围
console.log(Number.MAX_VALUE); //数字的最大值
不要用小数去验证小数,其中有个bug
(4) 伪数组: arguments
function f1(){ coneole.log(‘xxxxxx’) } f1() // f1指的是函数名,存储的是f1中的所有代码, 比如:console.log(f1)
结果是:
f f1(){
coneole.log('xxxxxx')
}
匿名函数
匿名函数不能直接调用
var f2=function (){ //函数表达式
console.log("xxxxxx");
};
将匿名函数直接赋值给f2了,解决了匿名函数不能直接用的问题!
匿名函数的调用:
f2();
特殊:f1() 小括号前是函数的代码;
f1() 同理想到—-> (函数代码)() —–>(function(){console.log(“xxxx”)};)()
函数的自调用(只能使用一次):
把一个函数给一个变量,此时形成了一个函数表达式! –> var 变量=匿名函数 注意:函数表达式后面赋值结束后,一定要有分号 !
函数名(); // 函数的调用
回调函数
函数可以作为参数使用,如果一个函数作为参数,那么,我们说这个参数(函数)可以叫做, 回调函数; 只要看到一个函数作为参数使用了,那就是回调函数!
1.js没有块级作用域(函数除外); 2.隐式全局变量:没有用var声明的变量,叫做隐式全局变量.
function f1(){
num=100;// 这是个隐式全局变量,外面也可以访问
} **3.全局变量是不能被删除的,隐式全局变量是可以被删除的,定义变量使用var是不会被删除的,没有var是可以删除的.** **4.函数调用之前,会把函数的声明提升到这个函数作用域的上面, **
预解析
js解析器在执行js代码的时候,分为两个过程,预解析过程和执行过程.
- 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值;
- 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用;
- 先提升var,在提升function;
预解析中,变量的提升只会在当前的作用域中提升,提前在当前的作用域的最上面,函数中的变量只会提升到函数的作用域的最前面,不会出去.
f1(); // 调用 -->函数调用之前,会把函数的声明提升到这个函数作用域的上面
var num=20; //这个变量的声明会提升到变量的使用之前.---->也就是说声明在前,赋值在后(预解析).
function f1() {
console.log(num)
var num =10;
};
面向过程:凡事都要其力亲为,每件事情的具体过程都要知道,注重的是过程.(单身) 面向对象:根据需求找对象,所有的事情都要对象来做,注重的是结果.(对象)
创建一个对象:
var obj=new Object(); //Object是系统的构造函数
obj.name=gankai; //直接可以声明属性
obj.say=function (){console.log("xxxx");}; //直接声明方法,匿名的.
obj.say();
函数和构造函数的区别:构造函数的名字首字母是大写的,普通函数不是;
自定义构造函数
var Person(name, age){ // 构造函数
this.name=name;
this.age=age;
this.play=function () {
console.log("xxxxx");
};
}
var per=new Person("张三",29); 创建一个对象,实例化一个对象,并且初始化,
var per =new Person("小米",20); 做了四件事:
- 在内存中开辟了空间,存储了新的对象,
- 把this设置为当前对象,
- 设置对象的属性和方法值,
- 返回创建后的新对象
可以用 obj instanceof Person 来判断对象的所属类型
用字面量形式创建对象,
var obj={}; // 缺点是:一次性使用!
另一种方式设置和获取对象的属性和方法
如何变量对象?
变量对象,不能通过for循环来变量,对象是无序的. 下面中,key是一个变量,这个变量中存储的是该对象的所有的属性的名字, for(var key in obj){ console.log(obj[key]); //输出所有对象的属性的名字 };
值类型传递的数据是值传递 引用类型传递的是地址
js学习中的三种对象
- 内置对象;——–js系统自带的对象
- 自定义对象;——自己定义的
- 浏览器对象
参考MDN 离线文档
https://developer.mozilla.org/zh-CN/
字符串的不可变性
原因是:str的指向发生了改变,只有一个str!
数组的几个要记住的方法
- .push(值);—>把值追加到数组中,所追加的数放到最后,返回值是追加之后的数组的长度,
- .pop();——>删除数组中的最后一个元素,返回值就是删除的这个元素的值;
- .shift();—->删除数组中的第一个元素,返回值就是删除的这个元素的值;
- .unshift();–>向数组的第一个元素的前面插入一个新的元素,返回值是插入之后的数组的长度;
- .map(函数);—>数组中的每个元素都要执行这个函数,把执行后的结果重新全部的放在一个新的数组中返回
基本包装类
一个需要注意的问题:函数f加不加括号的问题
图中,f2后面没有加(),是将f2的代码放在onclick中让onclick去执行,如果是f2(),则是f2自己这个函数去执行,直接执行了.
for循环是在页面加载的时候执行的,事件是在触发的时候执行的!
disabled====>禁用的;readonly======>只读的
对于网页的开关灯,给body标签设置添加一个class属性的style样式为black就行了,而且,document.body可以直接获得body对象;
阻止超链接默认跳转的几种方法
第三种写法
区别是第三种方法是将代码直接给onclick事件,第二种方法是onclick事件去执行f1函数
获取元素的方式
- 根据ID属性获取元素,返回来的是一个对象, document.getElementById(“id”)
- 根据标签名字获取元素,返回来的是一个数组,里面保存了多个DOM对象 document.getElementById(“标签名字”)
- 根据name属性的值获取元素,返回来的是一个伪数组,里面保存了多个DOM的对象, document.getElementByName(“name的属性值”)
- 根据class 的样式名字来获取元素,返回来的是一个伪数组,里面保存了多个DOM的对象, document.getElementByClassName(“类名”)
- 根据选择器获取元素,返回来的是一个元素对象. document.querySelect(“选择器的名字比如:#id”)
- 根据选择去获取元素,返回来的是一个伪数组,里面保存了多个DOM对象,
如果一个属性在浏览器中不支持,那么这个属性的类型就是undefined
如何判断浏览器的兼容性?
在脚本<script>
标签中定义这个方法,就可以直接用了!
如何给标签设置自定义属性?
在html标签中,添加的自定义的属性,如果想要获取这个属性的值,需要使用getAttribute(“自定义属性的名字”),才能获取到这个属性的值.
设置自定义属性:
移出某个标签的自定义的属性 removeAttribute(‘scope’)
tab切换模块=======>原理是排他性
思路:
根据上面tab的index索引,下面的对应的div改变颜色!
什么是节点(node)
答案是:标签,属性 ,文本(文字 空格 换行 )
概念: 文档:document 元素:页面中的所有标签,元素 节点:页面中的所有内容(标签,属性,文本(文字,空格,回车换行)) 根元素:html标签
节点的属性
- 可以使用标签元素点出来,属性节点点出来,
- nodetype,节点的类型,1–>节点,2—>属性,3—>文本
- nodename,节点的名字,标签节点—>大写的标签名字,属性节点—>小写的属性名字,文本节点—->#text
- nodevalue,节点的值:标签节点—null,属性节点—属性值,文本节点—文本内容.
单复选框的全选和单选
思路:
元素创建的三种方式:
- document.write(“标签的代码内容”)——>会覆盖页面上的所有内容.
- 对象.innerHTML=’标签及代码’;document.body.innerHTML=”<p>这是一个p标签</p>”
- document.createElement();
用原生DOM,注册一个鼠标点击事件,document.getElementById(“标签的Id”).onclick=function(){写鼠标点击后的代码}
如果是循环的方式添加事件,循环中的函数,推荐用命名函数,如果不是循环的方式添加事件,推荐用匿名函数.**也就是说,循环中,最好是用命名函数比较好,这样可以节省空间.
百度新闻免费代码
标签的css样式和DOM的css样式
图中的tableObj.border=’1’,是标签自带的border,给标签添加css属性,这样整个table标签中的tr 和td都有border属性,但是如若是tableObj.style.border=’1px solid red’ 这样是DOM属性,只有table有属性,table中的tr和td没有border属性.
点击一次只创建一个按钮! 思路1:有则删除,无则创建
看一下区别:
这样的创建是,边创建,边删除(效率不是太好).
思路2:不存在,就创建,存在就维持原样,不做任何操作
如何为一个元素标签绑定多个事件?
注意:对于IE8,可以用这个对象.attachEvent(“有on的事件类型”,事件处理函数),这个只有IE8支持
为任意元素,绑定任意事件##
方法和函数的区别:方法需要通过对象点才能调用执行(对象.sayHi();),函数可以直接使用(sayHello();)
一句话,方法是有人调,函数是没有人调.
为对象添加多个点击事件
绑定事件的区别
解绑事件
如何解绑事件?
用什么样的方式绑定事件,就应该用什么样的方式解绑事件,
- 解绑事件,==>对象.on事件名字=null,——–>解绑事件,
- 解绑事件,==>对象.removeEventListenner(‘没有on的事件类型’,命名函数,false);
- 解绑事件,==>detachEvent(‘on事件类型’,命名函数)
为任意的元素,解绑对应的事件
事件冒泡
如何设置阻止事件冒泡的事件.
事件的三个阶段:
- 事件捕获阶段–>从外向里(true)
- 事件目标阶段
- 事件冒泡阶段–>从里向外(false)
为同一元素绑定多个不同事件,指向相同的事件处理函数
类似百度搜索的联想输入框
项目目录URL:./Projects/js_demo
浏览器事件
window.onload=function(){};//页面加载的时候,触发的事件, window.onunload=function(){};//页面关闭之后,触发的事件, window.onbeforeunload=function(){};//页面关闭之前触发的事件,
location对象
location对象的属性和方法
几种需要记住的属性和方法
history的一些属性(了解)
history.back()//页面后退 history.forward()//页面前进 history.go()// 输入你想进入的地址
扩展:
(一):window.navigator.userAgent // 用于判断浏览器的参数
结果:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
(二):window.navigator.platform // 可以判断浏览器所在的平台的系统平台类型
结果:w32
定时器的开始和结束
一些案例 –>摇起来##
点击鼠标移动div
备注:用 my$(‘dv’).style.left,这个方法,只能获取到div这个标签属性中的left,获取不到在<style>
这个标签中定义的left,所有用offsetLeft,这个方法,都可以获取到.
封装动画函数
为了让定时器只启动一次,在启动定时器的时候,先清理定时器.
完整轮播图webapi第五天
offset系列
扩展:克隆,
谁调用这个克隆的方法,谁就被克隆.
图片跟着鼠标移动
第六章#
1.scrool 系列
相关介绍如下:
div.scrollHeight,这个是卷出去的距离.即,卷出div的距离.
获取任意一个元素的任意一个属性的当前值
变速动画函数,封装,任意多个属性,和回调函数,及层级,还有透明度!
function animate(element, json, fn) {
clearInterval(element.timeId);//清理定时器
//定时器,返回的是定时器的id
element.timeId = setInterval(function () {
var flag = true;//默认,假设,全部到达目标
//遍历json对象中的每个属性还有属性对应的目标值
for (var attr in json) {
//判断这个属性attr中是不是opacity
if (attr == "opacity") {
//获取元素的当前的透明度,当前的透明度放大100倍
var current = getStyle(element, attr) * 100;
//目标的透明度放大100倍
var target = json[attr] * 100;
var step = (target - current) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
current += step;//移动后的值
element.style[attr] = current / 100;
} else if (attr == "zIndex") { //判断这个属性attr中是不是zIndex
//层级改变就是直接改变这个属性的值
element.style[attr] = json[attr];
} else {
//普通的属性
//获取元素这个属性的当前的值
var current = parseInt(getStyle(element, attr));
//当前的属性对应的目标值
var target = json[attr];
//移动的步数
var step = (target - current) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
current += step;//移动后的值
element.style[attr] = current + "px";
}
//是否到达目标
if (current != target) {
flag = false;
}
}
if (flag) {
//清理定时器
clearInterval(element.timeId);
//所有的属性到达目标才能使用这个函数,前提是用户传入了这个函数
if (fn) {
fn();
}
}
//测试代码
console.log("目标:" + target + ",当前:" + current + ",每次的移动步数:" + step);
}, 20);
}
code/webapi/第六章/04源代码/11变速动画函数封装增加任意多个属性和回调函数及层级还有透明度.html
旋转木马
复习:arr.unshift(“x”)//向数组最前面添加一个x ;
arr.pop()//将数组的最后一个元素删除并返回这个删除的元素;
arr.shift(“x”)// 删除数组中的第一个元素,并返回这个被删除的元素;
arr.push(“x”)向数组最后添加一个元素’x’
clinet系列
clinet系列:可视区域 简介如下图:
图片跟着鼠标移动(鼠标移动事件)
第七章
- offset系列
- scroll系列
- client系列
插入: for/in 循环的一些注意事项,这个循环是用来更方便的遍历对象属性成员:
var obj={x:1,y:2,z:3};
for(var i in obj){
console.log(obj[i])
};
输出结果:1 2 3
var obj={x:1,y:2,z:3};
var arr=[] ,i=0;
for(arr[i++] in obj);
输出结果:arr ["x", "y", "z"]
for/in 循环不会遍历对象的所有属性,只有’可枚举的’属性才会被遍历到,对于稀疏数组中的属性,无法遍历出来,对象可以继承其他对象的属性,那些继承的自定义属性名,也可以遍历出来.
arr.unshift(‘xx’),是向前添加一个’xx’元素,并返回数组的长度
测试:
var arr=[{name:'张三',age:23,address:'深圳'},{name:'李四',age:33,address:'北京'}];
arr.map(fuction(e){return e.name;});
图片跟着鼠标飞行
//图片跟着鼠标飞,可以在任何的浏览器中实现
//window.event和事件参数对象e的兼容
//clientX和clientY单独的使用的兼容代码
//scrollLeft和scrollTop的兼容代码
//pageX,pageY和clientX+scrollLeft 和clientY+scrollTop
//把代码封装在一个函数
//把代码放在一个对象中
var evt={
//window.event和事件参数对象e的兼容
getEvent:function (evt) {
return window.event||evt;
},
//可视区域的横坐标的兼容代码
getClientX:function (evt) {
return this.getEvent(evt).clientX;
},
//可视区域的纵坐标的兼容代码
getClientY:function (evt) {
return this.getEvent(evt).clientY;
},
//页面向左卷曲出去的横坐标
getScrollLeft:function () {
return window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft||0;
},
//页面向上卷曲出去的纵坐标
getScrollTop:function () {
return window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop||0;
},
//相对于页面的横坐标(pageX或者是clientX+scrollLeft)
getPageX:function (evt) {
return this.getEvent(evt).pageX? this.getEvent(evt).pageX:this.getClientX(evt)+this.getScrollLeft();
},
//相对于页面的纵坐标(pageY或者是clientY+scrollTop)
getPageY:function (evt) {
return this.getEvent(evt).pageY?this.getEvent(evt).pageY:this.getClientY(evt)+this.getScrollTop();
}
}; //最终的代码
my$("im").style.left=evt.getPageX(e)+"px";
my$("im").style.top=evt.getPageY(e)+"px";
};
如果点击a标签不做任何跳转,可以这样做
<a href="javascript:void(0);"></a>
可以设置点击的时候,返回false,阻止a标签的默认跳转,和阻止事件冒泡
设置鼠标移动的时候,文字不被选中:
window.getSelection?window.getSelection.removeAllRanges():document.selection.empty();
元素隐藏的不同方式:
隐藏div
- 不占位置:document.getElementById(‘id’).style.display=’none’;
- 占位置的:document.getElementById(‘id’).style.visibility=”hidden”;
字符串的不可变性质:
var str= ‘qbsdfs’; str[1]=A; console.log(str);//结果还是: qbsdfs, 原样是:字符串的指向改变了,但是值没有改变
var str= ‘qbsdfs’; str=’456’; console.log(str); 结果是:456; 原来指向字符串:qbsdfs,现在指向456,但是内存没有改变,如果指向变多,大量的开辟储存空间,内存消耗大.
原形对象的相关知识:
原形的简单方法,手动修改原形构造器的指向,
原形中的方法可以相互调用
实例对象中所使用的方法和属性,先在实例中查找,找到了,则直接使用,找不到,则去实例对象的__protot__所指向的原形对象prototype中查找,找到了则使用,找不到则报错
为系统内置对象添加原形方法,
例如:Array.prototype.sayHi=function(){ console.log(this+”呵呵”) }
var arr=’xxx’; arr.sayHi();
局部变量变成全局变量,
原形和原形链之间的关系
实例对象的原形__proto__指向的是该对象所在的构造函数的原形对象
构造函数的原形对象(prototype)的指向如果改变了,实例对象的原形(__proto__)指向也会发生改变,原形的指向是可以发生改变的.
实例对象和原形对象之间的关系是通过__proto__原形来链接起来的,这个关系就是原形链.
** 当试图从一个对象中找到某个属性的时候,如果这个对象本身没有这个属性,那么会去这个对象的__proto__属性的值中查找(也就是这个对象的构造函数的prototype属性中查找),因为这个原型属性的值是一个对象(原型对象),既然是原型对象,那么只要是对象那么肯定会有构造函数,这个构造函数肯定会有prototype这个属性,然后这个prototype属性的值也是对象,以此类推,一直查找!**
let obj ={} obj.__proto__ === Object.prototype
所有引用类型的隐式原型对象(__proto__
)完全等于这个引用类型对象的构造函数的显示原型对象(prototype
)
原形的继承
函数声明和函数表达式的区别
函数的声明: function foo(){ };
函数表达式: var foo =function(){ };
函数中的一些对象
函数作为返回值以及函数作为参数的作用地方
预解析
所谓的预解析,就是在浏览器进行解析代码之前,将变量的声明或者函数的声明提升到该作用域的最上面
instanceof 是用来判断引用类型属于那个构造函数的方法
// 变量的提升 console.log(num) //结果出现undefined var num =200;
//函数的声明被提前了 f1(); function f1(){ console.log(‘这个函数能执行 ‘) }
f2(); var f2=funcrion(){ console.log(‘不能执行到这来’); }
重要:函数和变量的声明能提升,也就是能进行预解析,但是赋值
不能进行预解析,如果出现undefined,说明这个函数或者变量已经进行了声明,但是没有进行赋值.
闭包的作用,概念,作用,优点和缺点
一个函数的作用域,是在他定义的时候确定的,并不是在他执行的时候确定的
闭包的使用场景 1.函数作为返回值; 2.函数作为参数传递.
1.
function Fu (){
var a = 100 ;
return function (){
console.log(a) // a 属于自由变量 会去父级作用域找
}
}
var a=200
var f=Fu();
f(); // 100
2.
` function Fu(){ var a = 100; return function (){ //函数是在这时候声明定义的,那么这个a 就是这里作用域中的a 这个就是闭包; console.log(a) // a 属于自由变量 会去父级作用域找 } } var f = Fu(); function Fu2 (fu){ var a = 200 ; fu(); } Fu2(f);// 100 `
沙箱
递归求和
浅拷贝
深拷贝
正则表达式
^ 表示的是 以什么开始,或者是取非(反),
创建正则表达式的2种方式
在浏览器中输入: escape(‘你好’); 可以将中文转换为字符编码 同时用unescape(‘%u4F60%u597D’)可以将字符编码转换成中文
封装正则表达式
g是全局替换,i是忽略大小写