1、 基本语法
1.函数中声明变量不使用var 就是全局变量,变量不使用var,属于window的一个属性
2.Js数据类型 Number,String,Array,Date
3. 调用属性方式
4. 时间对象
5. js中array 就是java list和stack
6. 事件绑定方式2
7. window api 定时器
8. 节点概念
代码实现:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
window.onload=function(){
// 1.函数中声明变量不使用var 就是全局变量,变量不使用var,属于window的一个属性
function fn1(){
c=100;
}
fn1();
console.info(c);
// 2.Js数据类型 Number,String,Array,Date
var a1="11";
// Js进行强制类型转化,String->Number
console.info(Number(a1)+1);
// NaN来源, 不是数字类型转化为NaN
console.info(Number("abc"));
// parseInt把开头是数字的字符串转化为数字,如果开头不是数字,那就是NaN
var b1= "12px";
console.info(parseInt(b1));
// 判断类型
console.info((typeof b1)+"");
var c1= (b1 instanceof Number);
console.info(c1+"");
var d1; // undefined这个变量就是,Js中 NaN,undefined,0这个三个数false,其他的都是true
console.info(d1);
// 3. 调用属性方式
function Person(name){
this.name=name;
}
var p2=new Person("小明");
console.info(p2.name);
console.info(p2["name"]); // 当属性是变量的时候
// 获取对象所有属性 for-in语法
for(var a2 in p2){
console.info(a2,p2[a2]);
}
// 4. 时间对象
var d2=new Date();
// document.write("年:"+d2.getFullYear()+"月:"+(d2.getMonth()+1)+"日:"+d2.getDate()+"星期:"+d2.getDay()+"<br/>");
// 时间戳
// document.write("<br />"+Date.parse(new Date()));
// 5. String 和 java类似
var str2="abcdef";
console.info(str2.indexOf("a")); //搜索
console.info(str2.slice(1,2)); // [) 输出 b
console.info(str2.substring(1,2)); // [) 输出 b
console.info(str2.substr(1,2)); // 从1开始取2个字符 输出 bc
console.info("match",str2.match("adbc")); //输出匹配结果,失败返回null
// 例子
var s2="abc.txt"; //获取.txt前面的东西
console.info(s2.substring(0,s2.lastIndexOf(".")));
//5. js中array 就是java list和stack
var as2=new Array();
as2.push(1); //数组末尾插入,返回数组长度
console.info(as2);
var as21=[1,2];
console.info(as21);
// 把数组转化为字符串通过 * 连接
console.info(as21.join(","));
// sort自会通过字符串排序,自定义如果要通过整数
console.info(as21.reverse()); //倒叙
console.info("数据合并",as2.concat(as21));
// stack api
// shift: 删除返回数组第一个元素
// pop: 删除返回数组最有一个元素
// unshift:数组头部插入一个或者更多元素,返回数组长度
// 中间插入元素
// 从哪一个位置删除多少个元素,添加多少个
// 在索引为1的地方,之后删除1个元素,之后插入45,34
as21.splice(1,1,45,34)
console.info("splice",as21); //结果[2,45,34]
// 截取
var as212=[1,2];
console.info(as212.slice(1,2)); // [2]
// toString() 转化为字符串
// 6. 事件绑定方式2
var btn1= document.getElementById("btn1");
btn1.onclick=function(){
console.info(this.innerHTML);
}
// ul 下 li 时间绑定
var liArr= document.getElementById("content").getElementsByTagName("li");
for(var i=0;i<liArr.length;i++){
liArr[i].onmouseover=changColorRed;
liArr[i].onmouseout=chageBlack;
}
}
// 给ul下的li绑定事件
function changColorRed(){
this.style.color="#f00";
}
function chageBlack(){
this.style.color="#000";
}
// DOM1
// 简单事件
function clickD(obj){
console.info(obj.innerHTML);
}
// mouse事件
function mouseD(obj){
obj.style.fontSize="20px";
}
function out(obj){
obj.style.fontSize="10px";
}
// 事件绑定方式2 ,在onload中
// 7. window api 定时器
function show(){
console.info("show....");
}
// setTimeout(show,2000);
var timeId=setInterval(show,3000);
function stopD(obj){
clearInterval(timeId);
}
function goPage(obj){
window.location.href="test.html";
}
//8. 节点概念
function nodeT(){
/**
* <div name='属性节点'>abc</div>
* div: 元素节点
* name:属性节点
* abc: 内容节点
* https://www.cnblogs.com/xiaoleidiv/p/3347483.html
*/
var node= document.getElementById("node1");
console.info(node.innerHTML); //内容
console.info(node.nodeName); //名称
console.info(node.nodeType); // 类型
console.info("文本节点",node.firstChild.nodeValue,node.firstChild.nodeType);
}
</script>
</head>
<body>
<div onclick="clickD(this)">点击一下</div>
<div id="btn1">事件方式2</div>
<div onmouseover="mouseD(this)" onmouseout="out(this)">鼠标移动上来试试</div>
<div onclick="stopD(this)">停止</div>
<!-- BOM Api
Navigator: 浏览器对象,获取版本...
history: 返回上一个页面
locaton: 跳转到某一个页面,在js中
window: doucument(文档对象)
DOM Api:
document:
getElementById
getElementsByName: 名称,返回数组注意 a[0]
getElementsByTagName: 标签,返回数组注意 a[0]
节点概念:Node
-->
<a href="test.html">下一个页面</a> <br/>
<a onclick="goPage(this)">跳转到某一个页面</a> <br/>
<a href="#" onclick="window.open('test.html','name','width=300,height=300,resizable=0')">打开窗口</a>
<div onclick="nodeT()" id="node1" style="cursor: pointer;">节点概念</div>
<ul id="content">
<li>语文</li>
<li>数学</li>
<li>英语</li>
<li>化学</li>
</ul>
</body>
</html>
2、函数对象
9. 函数与对象内存各自关系
10. js函数重载
11. 函数是一个对象,那么可以做为参数传递,函数返回值
12. 排序 案例
13. 函数参数,通过arguments获取参数
14. 函数call apply
15. 对象,创建对象
16.Js中闭包:
17. 正则表达式
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="shortcut icon" href="#" />
<script type="text/javascript">
window.onload=function(){
/**
* 9. 函数与对象内存各自关系
*/
function f1(){
console.info("f1");
}
var f2=f1;
f2();
/**
* var f2=f1: 把函数在内存中拷贝了一份
* f1变了,不会影响f2,函数拷贝
*/
var obj={
msg:"hello",
}
var obj1= obj;
obj1.msg="jack";
console.info(obj.msg);
/**
* 对象是通过引用来赋值,修改obj1,obj的值也会被修改
* obj1、obj在栈中指向 堆中{}数据
*/
/**
* 10. js函数重载
*/
function sum1(a,b){
return a+b;
}
function sum1(a){
return a;
}
console.info(sum1(10,10)); //10
console.info(sum1(10)); //10
/**
* 输出的结果都是10为什么
var sum=function(a,b){
return a+b;
}
// sum支持函数function(a,b)
var sum=function(a){
return a;
}
// sum 支持函数function(a)
// 那么funciton(a,b)已经不存在了
// 结果:js函数的调用和函数参数没有什么关系,函数不存在重载
*/
/**
* 11. 函数是一个对象,那么可以做为参数传递
* 1.函数回调
* 2.函数作为返回值
*/
function callFun(fun,arg){
return fun(arg);
}
function say(str){
alert(str);
}
//callFun(say,"hello");
//2.函数作为返回值
function returnF(arg){
var rel= function(num){
return arg+num;
}
return rel;
}
var r1= returnF(10);
var r2= r1(20);
//alert(returnF(10)(20));
// 函数作为返回值使用
// 12. 排序
function sortByNum(a,b){
return a-b;
}
var list=[1,16,4,3]; //可以包含字符串 "11"-1 =10 js可以自动转化
list.sort();
console.info("默认排序",list); //js 默认数字也是按照字符串来排序
list.sort(sortByNum) // 自定义排序
console.info("之定义排序:",list);
// 测试对象,js创建对象
function Person(name,age) {
this.name = name;
this.age = age;
}
var p1 = new Person("Leno",39);
var p2 = new Person("John",23);
var p3 = new Person("BB",431);
var p4 = new Person("BB",56);
var ps = [p1,p2,p3,p4]; // 如果要使用sort函数,那么必须要自定义规则
function sortByName(obj1,obj2){
if(obj1.name > obj2.name){
return 1;
}else if(obj1.name == obj2.name){
return 0;
}else {
return -1;
}
}
function sortByAge(obj1,obj2) {
return obj1.age-obj2.age;
}
// ps.sort(sortByName,sortByAge) // 根据多个属性排序
// console.info(ps);
// 上面代码问题,如果有多个属性需要些多次,可以写一次吗??
// 如何实现只需要返回上面函数即可
function sortbyProperty(propertyName){
return function(obj1,obj2){
if(obj1[propertyName]>obj2[propertyName]){
return 1;
}else if(obj1[propertyName] == obj2[propertyName]){
return 0;
}else {
return -1;
}
}
}
ps.sort(sortbyProperty("name"))
function show() {
var p = document.getElementById("person");
for(var i=0;i<ps.length;i++) {
p.innerHTML+=ps[i].name+","+ps[i].age+"<br/>";
}
}
show();
/**
* 13. 函数参数,通过arguments获取参数
* 谁调用函数,函数中this就是谁
* show(): this是 window
* person.show() this就是Person
*/
function showArgs(num){
console.info("argumnt:",arguments.length); // 函数实际传参个数 这里是3
console.info("length:",showArgs.length) // 函数形参个数 这里是1
for(i=0;i<arguments.length;i++){
console.info(arguments[i]);
}
}
showArgs(2,3,4);
// arguments.callee 可以得到当前函数,避免函数名称变化
function factorial(num){
if(num<1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
console.info("5的阶乘",factorial(5));
/**
* 14. 函数call apply
*/
// 基本用法
function sumC(num1,num2){
return num1+num2;
}
/**
* 用法:参数不同 第一个参数是对象,第二个是数组|参数列表
*/
function callSumC(num1,num2){
return sumC.apply(this,arguments);
// 或者
// return sumC.apply(this,[num1,num2]);
// 或者
return sumC.call(this,num1,num2);
}
console.info("apply...call调用函数:",callSumC(3,4));
/**
* 用途1: 对象中不需要定义方法也可以调用
*/
var color="red";
function showColor(color){
console.info("showColor",color);
}
function Circle(color){
this.color=color;
this.say=function(){
console.info("I am a circle");
}
}
var c=new Circle("black");
showColor.call(c,"black"); // c中没有定义showColor函数,通过c来调用
showColor("yellow"); // 通过window来调用
/**
* 15. 对象,创建对象
*/
// 方式1. 使用new
var man= new Object();
man.name="小明";
man.age=20;
man.say=function(){
alert("say...man");
}
//man.say();
c.say();
// 直接使用json
var man1={
name:"李四",
say:function(){
alert("say..man1");
}
}
// man1.say();
// 通过Json创建集合
var manList=[
{name:"leon",age:22},
{name:"ada",age:45}
];
for(var k=0;k<manList.length;k++){
console.info("通过json创建集合",manList[k].age+ " "+ manList[k].name);
}
}
/**
* 3.通过构造函数方式创建对象,这里必须要用this,否则color、say属于window
*/
function Round(color){
this.color=color;
this.say=function(){
console.info("I am a Round");
}
}
var r1= new Round("red");
var r2= new Round("blue");
r1.say();
// 问题, false ,
// 该函数在栈中this.say,每创建衣一个对象,都会存在一个方法的拷贝,如果对象很多的话,占用空间比较大
var r_result = ( r1.say == r2.say )
console.info("结果是",r_result);
// 解决方法, 将行为设置为全局函数
// 问题:全局函数属于window,不利于封装,解决方法,原型
function Round4(color){
this.color=color;
this.say = say2;
}
function say2(){
console.info("i am a Round2");
}
var r4=new Round4("yellow");
console.info("Round4是....:",r4.say == r4.say );
/**
* Js中原型: 自定义类、继承??? 放一下???
*/
/**
* 匿名函数和普通函数
* 函数作用域:https://blog.csdn.net/dreams_deng/article/details/102148012
*/
// 对于普通函数,可以在声明前调用函数不会报错,函数永远会被最先初始化
fn1();
function fn1(){
console.info("普通函数","fn1");
}
// 如下定义函数,不会被执行,如果在声明之前调用函数会报错
// 这个函数开始是没有名称的,这个函数就是叫做匿名函数
var fn3= function(){
console.info("匿名函数","fn3");
}
fn3();
/**
* 16.Js中闭包:
* 执行compareObjectFunction 函数以后,理论上形参 prop 里面的函数 在栈中 都会被内存释放
* 但是 返回匿名函数,作用域扩大,内存不会被释放
* 通过返回函数来扩大作用域的方法就是闭包
*/
function compareObjectFunction(prop){
// 这个就是匿名函数,return 返回的
return function(obj1,obj2){
if(obj1[prop]>obj2[prop]){
return 1;
}else if(obj1[prop] == obj2[prop]){
return 0;
}else {
return -1;
}
}
}
var o1={name:"any",age:34};
var o2={name:"tony",age:1};
var compare= compareObjectFunction("name");
console.info("闭包结果是:",compare(o1,o2));
/**
* 闭包带来问题
*/
var arr=new Array();
for(var i=0;i<10;i++){
arr[i]=function(){
return i;
}
}
// 输入传递内容都是10
// 此事通过闭包来调用函数,当输出i的时候会去上一级作用域中查找,这个时候ii已经是10,所以会连续输出10个10
for(var k=0;k<arr.length;k++){
console.info("闭包问题1",k+" "+arr[k]());
}
// 上面问题解决方法,把i 和函数 都保存到数组中
var arr5=new Array();
for(var i=0;i<10;i++){
var tf=function(num){
// 调用该函数的时候回去上一级作用域中查找,tf一直都在
arr5[num]=function(){
return num;
}
}
// 调用函数
tf(i);
}
for(var k=0;k<arr5.length;k++){
console.info("解决闭包问题:",arr5[k]());
}
/**
* 新问题:回调函数中的this
*/
var name1="weixing";
var weiF= {
name1:"qq",
showMsg:function(){
return function(){
return this.name1;
}
}
}
/**
* 调用weiF.showMsg()的时候,这个函数作用域已经结束了,
* 函数结束之前this指向weiF, 之后指向window
*/
console.info("对象中闭包中this",weiF.showMsg()());
// 解决
var weiF= {
name1:"qq",
showMsg:function(){
var that=this;
return function(){
return that.name1;
}
}
}
console.info("对象中闭包中that:",weiF.showMsg()());
/**
* js中没有块作用域:
* 这个变量在window下定义,给windowt添加变量
*/
for(var i=0;i<10;i++){
}
// alert(i); // 输出的结果是10
// 解决
// 在还引入多个js文件的时候,变量污染混乱
// 每个人开发的代码放入下面
(function(){
}())
// js中如何封装使用变量
function Person(){
this.setName=function(value){
name=value;
}
this.getName=function(){
return name;
}
}
var ppp = new Person("aa");
ppp.setName("bb");
console.info("js中属性封装",ppp.getName());
/**
* 17. 正则表达式
* 扩充已经存在类的原型,去除前后空格
* 复习:
* /s /d /D /w /S
* [] {}
* * + ? ^ $
* /g /i
*/
String.prototype.trim=function(){
return this.replace(/(^\s+)|(\s+$)/g,"");
}
/**
* 去除所有空格
*/
String.prototype.trimAll=function(){
return this.replace(/\s+/g,"");
}
var hh="A 憨憨 ";
console.info("扩充原型:",hh.trim());
console.info("去除所有空格",hh.trimAll());
</script>
</head>
<body>
<div id="person"></div>
</body>
</html>