数据类型
js有六种数据类型,包括五种基本数据类型和一种复杂数据类型
>>基本数据类型:Number、String、Boolean、Undefined、Null
-
Number类型 包含整数和浮点数(浮点数数值必须包含一个小数点并且小数点后面最少跟一个数字)两种值
NaN:非数字类型。特点:涉及到任何关于NaN的操作,都会返回到NaN;NaN不等于自身
-
String类型
字符串有length属性字符串转换:转型函数String(),适用于任何数据类型(null和undefined转换后为null和undefined) toString()方法(null和undefined没有toString()方法)
-
Boolean类型 只有两个值,true和false
-
Undefined类型 只有一个值,undefined。使用var 声明了变量,但是未给var初始化,那么这个变量的值就是undefined
-
null类型 null类型被看做空对象指针
-
object类型 js中对象是一组属性与方法的集合。
这里要说到引用类型,引用类型是一种数据结构,用于将数据和功能组织在一起。 引用类型有时候也被称为对象定义,因为他们描述的是一类对象所具有的属性和方法。
三大引用类型
1. Object类
我们看到的大多数类型值都是Object类型的实例,创建Object实例的方式有两种。
第一种是使用new操作符后跟Object构造函数,如下所示
var person = new Object();
person.name = “Micheal”;
person.age = 24;
第二种方式是使用对象字面量表示法,如下所示
var person = {
name : “Micheal”,
age : 24
};
2.Array类
数组的每一项可以用来保存任何类型的数据,也就是说,可以用数组的第一个位置来保存字符串,第二个位置保存数值,第三个位置保存对象…另外,数组的大小是可以动态调整的。
创建数组的基本方式有两种
第一种是使用Array构造函数,如下所示
var colors = new Array(“red”,“blue”,“yellow”);
第二种是使用数组字面量表示法,如下所示
var colors = [“red”,“blue”,“yellow”];
3.function类型
每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。函数通常是使用函数声明语法定义的,如下所示
function sum(num1,num2){
return num1 + num2;
};
这和使用函数表达式定义函数的方式相差无几。
var sun = function (){
return sum1 + sum2;
};
也就是说,js按照存储方式分为值类型和引用类型,区别如下:
题目1: var a = 100;
var b = a;
a = 200;
console.log (b);
题目2: var a = {age : 20};
var b = a;
b.age = 21;
console.log (a.age);
题目1的答案是 100,题目2的答案是21,
题目1是简单的值类型,在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上。
此时,a中保存的值为 100 ,当使用 a 来初始化 b 时,b 中保存的值也为100,但b中的100与a中的是完全独立的,该值只是a中的值的一个副本,此后,
这两个变量可以参加任何操作而相互不受影响。也就是说基本类型在赋值操作后,两个变量是相互不受影响的。
题目2是引用类型,当从一个变量向另一个变量赋值引用类型的值时,同样也会将存储在变量中的对象的值复制一份放到为新变量分配的空间中。
这时保存在变量中的是对象在堆内存中的地址,所以,与简单赋值不同,这个值的副本实际上是一个指针,而这个指针指向存储在堆内存的一个对象。那么赋值操作后,
两个变量都保存了同一个对象地址,则这两个变量指向了同一个对象。因此,改变其中任何一个变量,都会相互影响。
因此,引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。
数组
排他思想
利用for循环干掉所有,然后再设置自己的
DOM节点操作
访问关系
- 父节点
parentNode
- 兄弟节点
nextSibling 下一个兄弟节点 IE6、7、8适用
nextElementSibling 其他浏览器适用
previousSibling previousElementSibling
必须先写正常浏览器,再写IE6、7、8
- 子节点
firstChild IE6、7、8
firstElementChild 正常浏览器
lastChild lastElementChild
- 孩子节点
childNodes 选出全部的孩子
它是标准属性,返回指定元素的子元素合集,包括HTML节点,所有属性、文本节点
nodeType 来判断
nodeType == 1 元素节点
nodeType == 2 属性节点
nodeType == 3 文本节点
children 选取所有的孩子(只有元素节点)
IE6、7、8会包括注释节点
DOM节点操作
-
创建节点
var newLi = document.creatElement("li");
-
插入节点
appendChild(); 添加孩子,放到盒子最后面 insertBefore(插入的节点,参照节点) 子节点,添加孩子 写满两个参数 demo.insertBefore(test,childrens[0]); 放到了第一个孩子的前面 如果第二个参数 为 null 则 默认这新生成的盒子放到最后面。 demo.insertBefore(test,null);
-
移除节点
removeChild() 移除孩子节点 var da = document.getElementById("xiongda"); demo.removeChild(da);
-
克隆节点
cloneNode(); 复制节点 括号里面可以跟参数,如果是true则是深层复制,除了复制本盒子,还复制子节点;如果是false则是浅复制,只复制本节点,不复制子节点。
节点属性
- 获取节点属性 getAttribute(“title”)
- 设置节点属性 setAttribute(“class”,“one”)
- 删除节点属性 removeAttribute(“title”);
内置对象
内置对象就是指这个语言自带的一些对象,供开发者使用,这些对象提供了一些常用的或是最基本而必要的功能。
- 日期函数 Date()
可以设置本地日期,年月日 时分秒
常用方法:
获取日期和时间
getDate() 获取日 1-31
getDay () 获取星期 0-6
getMonth () 获取月 0-11
getFullYear () 获取完整年份(浏览器都支持)
getHours () 获取小时 0-23
getMinutes () 获取分钟 0-59
getSeconds () 获取秒 0-59
getMilliseconds () 获取当前的毫秒
getTime () 返回累计毫秒数(从1970/1/1午夜)
示例:
var date = new Date()
date.getTime();
- 定时器——setInterval(执行的函数,间隔时间ms)
每隔一段时间执行一次函数,特别像for循环,但他最大的特点在于自动,可以设定时间
写法
setInterval(“fun()”,1000) 可以用
setInterval(function(){},1000)
关闭定时器 clearInterval(定时器名称); 定时器不再进行
- 定时器——setTimeout(执行的函数,时间)
在规定的时间之后,执行一次函数,类似于定时炸弹
深层次看待两种定时器区别
setInterval是排队执行的,假如 间隔时间是1秒, 而执行的程序的时间是2秒 上次还没执行完的代码会排队, 上一次执行完下一次的就立即执行, 这样实际执行的间隔时间为2秒
假设setTimeout延迟时间为1秒执行,要执行的代码需要2秒来执行,那这段代码上一次与下一次的执行时间间隔为3秒
利用setTimeout来实现setInterval效果
在setTimeout执行的函数中递归调用setTimeout定时器
按钮不可用
btn.disabled = “disabled” || btn.disabled = true;
注意:
因为 button是个双标签 所以要更改他的值, 使用 innerHTML 的,不是value。
this
this指向的是事件的调用者,或者函数的使用者。
例如
var btn.onclick = function(){this;} //this指向事件的调用者 btn
setInterval(sendTextMessage,1000) //开启定时器
function(){
count--;
this.innerHTML = "还剩余"+count+"秒";
}//this 指向函数的使用者 setInterval
arguments对象
arguments对象是函数自动创建的一种类数组对象,用来接收函数所传入的参数值。
由于js语法不支持函数的重载,所以需要用arguments对象来模拟函数重载效果。
函数重载:相同函数名,不同参数列表的多个函数,在调用时,可根据传入的参数不同,自动选择对应的函数执行。
作用:
arguments[i] 获取下标对应的参数值
arguments.length 获取所传入函数的实参个数
arguments不是数组类型,不可使用数组API
function fn(a,b,c){
console.log(a+b+c);
alert(arguments.length;)
}
fn(1,3,4,6); //arguments.length; 返回的是 实参的个数。
//但fn执行的结果仍为前三个数的和
//但是这个对象有讲究,他只在正在使用的函数内使用。
//arguments.callee;
//返回的是正在执行的函数。 也是在函数体内使用。
//在使用函数递归调用时推荐使用arguments.callee代替函数名本身。
function fn(){
console.log(arguments.callee);
}
//这个callee 就是 : function fn() { console.log(arguments.callee); }
&&和||
a&&b 结果是什么?
若a为假,返回a,若a为真,返回b
var aa = 0&&1;
alert(aa) // 0
var bb = 1&&0;
alert(bb); //0
var cc = 1&&10;
alert(cc); // 10
a||b 结果是什么?
若a为假,返回b,若a为真。返回a。
0||1 //1
1||0 //1
1||5 //1
5||1 //5
字符串对象常用方法
转换为字符串
1. + “” 2+ “” = “2” 2+”ab” = “2ab”
2. String() 转换为字符串
3. toString(基数) ; 基数就是进制
var txt = 10;
txt.toString(2) 二进制 1010
根据位置返回字符
charAt(index),返回指定位置的字符(参数:字符位置) js中字符为长度为1的字符串
charCodeAt(index),返回指定位置字符的unicode编码
根据字符返回位置
1. 返回前面起第一个字符的位置
indexOf('字符');
//它是从前面开始数(左边开始数),而且只找第一个,然后返回该字符的位置,索引号从0开始,返回数值
var text= "abcdef";
console.log(text.indexOf('d')); //结果是3
//如果找不到,返回 -1
2. 返回后面起第一个字符的位置
lastIndexOf('字符');
var text = "abcdefabcdef";
text.lastIndexOf("d"); //返回9
//返回的值还是从 左边开始数的索引号
网址编码
- 把网址传入后台,需要进行编码
encodeURIComponent(URIstring) 可以把字符串作为URI组件进行编码
decodeURIComponent() 函数可把字符串作为 URI 组件进行解码
操作字符串
a.concat(b)合并字符串
eg:txt1.concat(txt2)
slice(‘取字符串的开始位置’,’[取字符串的结束位置]’)
两个参数都是索引号,第二个参数位置可选,省略的话则一直取到最后一个。
注:取到第二个索引值之前的那一个。
起始位置可以是负数,如果是负数则是从右边往左边开始取。
substr(起始位置,[取的个数])
不写取的个数,则按默认从起始位置一直取到最后
取的个数:是指从起始位置开始,往后面数取几个
起始位置为负数的话IE6、7、8会报错,尽量少用。
substr()与slice()区别:substr()始终会把小的值作为起始位置,大的值作为结束位置。例如 substr(6,3) 实际中会变成 substr(3,6)
保留小数位数(以保留 2位有效小数为例)
//通过indexOf()返回小数点的位置,然后利用substr截取字符串
1. console.log(str.substr(0,str.indexOf(".")+3));
//先乘以100,取整,然后除以100
2.console.log(parseInt(PI*100) /100);
//PI.toFuxed(2)保留两位小数
console.log(PI.toFixed(2));
大小写转换
1. toUpperCase() //转换为大写
2. toLowerCase() //转换为小写
asdf.toUpperCase()
$("txt").value.toUpperCase();
无缝滚动
原理:以四张图片为例,首先复制两张图(第一张和第二张)放到最后面(本质上变成了第五、六张),ul是不断向左移动的,如果ul的left值小于等于四张图片的宽度的负值,就将ul的left值快速复原为0。
缓动动画(一次过渡一张banner图)
原理:等差数列。
将ul的left值设为以图片宽度为公差的等差数列
js的位置和尺寸
offset 家族
- offsetWidth/offsetHeight
得到对象的宽度和高度(自己的,与他人无关)
offsetWidth = width + border + padding
- offsetLeft/offsetTop
返回与上级盒子(最近的且带有定位的)左边的距离,即对于已经定位的最近的父元素的左边距离
如果父级都没有定位则以body为准
子盒子到定位的父盒子边框到边框的距离
- offsetParent
返回该对象的最近的带有定位的父级,如果没有定位则返回body
offset家族与style.left、style.top的区别
最大区别在于offsetLeft/offsetTop可以返回没有定位的盒子距离左侧/顶部的距离,而style.left、style.top不可以。
offset返回的是数字,而style.left、style.top返回的是带有px的字符串
offset只读,而style.left、style.top可读可写。
如果没有给html元素指定过top样式,则style.top返回的是空字符串
最重要的区别,style.top只能得到行内样式,offsetLeft随便
screenX、pageX、clientX的区别
screenX/Y 以我们的电脑屏幕为基准点测量
pageX/Y 以文档(绝对定位)的基准点对齐
clientX/Y 以浏览器的可视区域,类似于固定定位
拖动原理
鼠标按下,移动鼠标
bar.onmousedown = function(){
document.onmousemove = function(){}
}
防止选择拖动
按下鼠标然后拖拽可以选择文字,而要清楚选中内容的话
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
scroll家族——scrollTop、scrollLeft
scrollTop 被卷上去的部分的高度
获取scrollTop的兼容性写法
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
scrollTo(x,y) 可以把内容滚动到指定的坐标
window.scrollTo(x,y);
冒泡机制
事件冒泡:当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。
顺序 div -> body -> html -> document -> window
以下事件不冒泡:blur、focus、load、unload
阻止冒泡方法
标准浏览器:event.stopPropagation()
IE浏览器:event.cancelBubble = true
兼容写法
1 if(event && event.stopPropagation)
2 {
3 event.stopPropagation(); // w3c 标准
4 }
5 else
6 {
7 event.cancelBubble = true; // ie 678 ie浏览器
8 }
三个取整函数
Math.ceil() 向上取整
Math.floor() 向下取整
Math.round() 四舍五入取整
缓动动画原理
匀速动画的原理:盒子本身的位置+步长
缓动动画的原理:盒子本身的位置+步长(不断变化的)
封装代码
1 function animate(obj,target){ // 第一个参数 动谁 第二个参数 动多少
2 clearInterval(obj.timer);
3 obj.timer = setInterval(function() {
4 // 计算步长 动画的原理 盒子本身的位置 + 步长
5 var step = (target - obj.offsetLeft) / 10; // 步长
6 step = step > 0 ? Math.ceil(step) : Math.floor(step); // 取整步长
7 // obj.style.left = 盒子本身的位置 + 步长
8 obj.style.left = obj.offsetLeft + step + "px";
9 if(obj.offsetLeft == target){
10 clearInterval(obj.timer);
11 }
12 },30)
13 }
json遍历
for(变量 in 对象) {执行语句;}
var json = {width:200,height:300,left:50}
console.log(json.width);
for(var k in json)
{
console.log(k); // k 遍历的是json 可以得到的是 属性
console.log(json[k]); // json[k] 得到 是属性的 值
}
in运算符
二元运算符,但对运算符左右两边的操作数要求比较严格。要求左边的操作数必须是字符串类型或可以转换为字符串类型的其他类型,而右边的操作数必须是数组或者对象。只有第一个操作数的值是第二个操作数的属性名,才会返回true,否则返回false。
// in 可以用用来判断 json 里面有没有某个属性
var json = {name: "andy",age : 15};
if("andy" in json)
{
console.log("yes"); // 返回的是 yes
}
else
{
console.log("no");
}
new 关键字
常利用new关键字去声明新的对象
其作用是创建一个对象实例。这个对象可以是用户自定义的,也可以是带构造函数的一些系统自带的对象
new关键字可以让this 指向新的对象
所谓“构造函数”,其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。
prototype 共同的、相同的
主要解决:函数因为使用非常非常多,重复执行效率太低
Person.prototype.showName = function() { // 用的共同的父亲
alert("我的名字是"+ this.name);
}
<!--类.prototype.方法 = function() {} 具体格式
可以把那些不变的属性和方法,直接定义在prototype对象上
使用方法:
类名.prototype.方法-->