JavaScript学习笔记

JS学习笔记

1.基本数据类型和变量

//Number类型
123; // 整数123
0.456; // 浮点数0.456
1.2345e3; // 科学计数法表示1.2345x1000,等同于1234.5
-99; // 负数
NaN; // NaN表示Not a Number,当无法计算结果时用NaN表示
Infinity; // Infinity表示无限大,当数值超过了JavaScript的Number所能表示的最大值时,就表示为Infinity

//字符串类型
'xxx'
"xxx"

//布尔类型
true
false

//null和undefined
null表示空
undefined表示

//数组
x = [1,2,3,4,'x',true,null,[1,3,4]];
//可通过索引调用
x[0]; //x[0]:1

//对象
var person = {
    name: 'Bob',
    age: 20,
    tags: ['js', 'web', 'mobile'],
    city: 'Beijing',
    hasCar: true,
    zipcode: null
};
//通过 类名.属性 访问
person.name;

//变量
//可以是任意数据类型
var x=1
var $b=2

//Map
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.set('Bob', 59); //添加新key-value
m.get('Michael'); // 95

//Set 其中元素不会重合
var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}
s.add(4); //添加新元素
//常量,无法被修改
const PI=3.14

2.strict模式

  • JavaScript在设计之初,为了方便初学者学习,并不强制要求用var申明变量。这个设计错误带来了严重的后果:如果一个变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量:
  • 不用var申明的变量会被视为全局变量,为了避免这一缺陷,所有的JavaScript代码都应该使用strict模式

3.判断与循环

  • 判断

    • if(){}else{}与c语言等类似
  • 循环

    • //for(){}
      var n=10;
      for(var i = 0; i < n; i++)
      {
      	console.log(i);
      }
      
    • //for in
      var x=['a','b','c'];
      for(var i in x)
      {
      	console.log(i);
      }
      
    • //while
      var n=5;
      while(n--)
      {
      	console.log(n);
      }
      
    • //do while
      var n=5;
      do{
      	cosole.log(n)
      }while(n--);
      
    • //for of
      var n=[1,2,3,4,5];
      for(var a of n)
      {
      	cosole.log(a);
      }
      

4.函数

  • 定义方式

    • function abs(x) {
          if (x >= 0) {
              return x;
          } else {
              return -x;
          }
      }
      
    • var abs = function (x) {
          if (x >= 0) {
              return x;
          } else {
              return -x;
          }
      };
      
  • arguments

    • 只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments类似Array但它不是一个Array
  • return的一些问题

    • 最好将return写到一行之中,否则可能会出错,因为JavaScript默认每行后面自动会加入;可能会导致错误产生
  • 函数可以嵌套

    • 内层函数可以访问外部函数的变量
    • 内层函数只能在外层函数之中使用
  • 变量提升

    • JavaScript会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部,所以可以先调用后定义,如下

      'use strict';
      
      function foo() {
          var x = 'Hello, ' + y;
          console.log(x);
          var y = 'Bob';
      }
      
      foo();
      
    • 因此使用函数时,先定义变量,一般通过以下方式操作

      function foo() {
          var
              x = 1, // x初始化为1
              y = x + 1, // y初始化为2
              z, i; // z和i为undefined
          // 其他语句:
          for (i=0; i<100; i++) {
              ...
          }
      }
      
  • 局部作用域

    function foo() {
        for (var i=0; i<100; i++) {
            //
        }
        i += 100; // 仍然可以引用变量i
    }
    //所以引入了let关键字
    for(let i=0; i < 100; i++)
    {
    	//        
    }
    cosole.log(i); //wrong
    
  • 解构赋值

    var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
    let [x, [y, z]] = ['hello', ['JavaScript', 'ES6']];
    let [, , z] = ['hello', 'JavaScript', 'ES6']; 
    
    //也可以从对象中取出想要的值
    var person = {
        name: '小明',
        age: 20,
        gender: 'male',
        passport: 'G-12345678',
        school: 'No.4 middle school'
    };
    var {name, age, passport} = person;
    var {name, single=true} = person; //解构赋值也可以使用默认值,防止出现undefined
    
    //一些用法
    //快速交换x,y的值
    var x=1,y=2;
    [x,y]=[y,x];
    
  • 方法

    • var that = this;,才可以放心地在方法内部定义其他函数,而不是把所有语句都堆到一个方法中,防止this指向undefined

    • apply

      function getAge() {
          var y = new Date().getFullYear();
          return y - this.birth;
      }
      
      var xiaoming = {
          name: '小明',
          birth: 1990,
          age: getAge
      };
      
      xiaoming.age(); // 25
      getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
      
    • call

      • 与apply基本一致,apply是将数据打包传入,call则是按顺序传入
  • map与reduce(与python中的基本一致)

    • 用map求数组每个值的平方

      function pow(x) {
          return x * x;
      }
      var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
      var results = arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
      
    • 用reduce求数组每个值的和

      var arr = [1, 3, 5, 7, 9];
      arr.reduce(function (x, y) {
          return x + y;
      }); // 25
      
  • 函数也可以作为返回值

  • 闭包

    • 延迟返回

      function count() {
          var arr = [];
          for (var i=1; i<=3; i++) {
              arr.push(function () {
                  return i * i;
              });
          }
          return arr;
      }
      
      var results = count();
      var f1 = results[0];
      var f2 = results[1];
      var f3 = results[2];
      
      f1(); // 16
      f2(); // 16
      f3(); // 16
      
    • 可以将变量绑定然后访问到外部本来访问不了的变量

  • 箭头函数

    • 类似于匿名函数

    • 要返回对象的时候

      x => ({ foo: x })
      
    • 箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj

5.对象

(1)Data

  • var date=new Date();
    

(2)RegExp

  • 作用:可以在JavaScript中使用正则表达式

  • //两种定义方式
    var re1 = /ABC\-001/;
    var re2 = new RegExp('ABC\\-001');
    
  • 匹配时间

    var re = /^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$/;
    re.exec('19:05:30'); // ['19:05:30', '19', '05', '30']
    
  • 全局搜索

    var r1 = /test/g;
    // 等价于:
    var r2 = new RegExp('test', 'g');
    
    //例子
    var s = 'JavaScript, VBScript, JScript and ECMAScript';
    var re=/[a-zA-Z]+Script/g;
    
    // 使用全局匹配:
    re.exec(s); // ['JavaScript']
    re.lastIndex; // 10
    
    re.exec(s); // ['VBScript']
    re.lastIndex; // 20
    
    re.exec(s); // ['JScript']
    re.lastIndex; // 29
    
    re.exec(s); // ['ECMAScript']
    re.lastIndex; // 44
    
    re.exec(s); // null,直到结束仍没有匹配到
    

(3)JSON

  • JSON中的数据类型

    • number:和JavaScript的number完全一致;
    • boolean:就是JavaScript的truefalse
    • string:就是JavaScript的string
    • null:就是JavaScript的null
    • array:就是JavaScript的Array表示方式——[]
    • object:就是JavaScript的{ ... }表示方式。
  • 序列化,将一个对象转为JSON格式的字符串

    var xiaoming = {
        name: '小明',
        age: 14,
        gender: true,
        height: 1.65,
        grade: null,
        'middle-school': '\"W3C\" Middle School',
        skills: ['JavaScript', 'Java', 'Python', 'Lisp']
    };
    var s = JSON.stringify(xiaoming);
    console.log(s);
    //{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":"\"W3C\" Middle School","skills":["JavaScript","Java","Python","Lisp"]}
    
  • 反序列化,将一个JSON对象变为一个JavaScript对象

    JSON.parse('[1,2,3,true]'); // [1, 2, 3, true]
    JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14}
    JSON.parse('true'); // true
    JSON.parse('123.45'); // 123.45
    
    • JSON.parse()还可以接收一个函数,用来转换解析出的属性

      var obj = JSON.parse('{"name":"小明","age":14}', function (key, value) {
          if (key === 'name') {
              return value + '同学';
          }
          return value;
      });
      console.log(JSON.stringify(obj)); // {name: '小明同学', age: 14}
      

6.面向对象

(1)创建对象

  • 构造函数(首字母大写,调用时用new)

    function Student(name) {
        this.name = name;
        this.hello = function () {
            alert('Hello, ' + this.name + '!');
        }
    }
    var xiaoming = new Student('小明');
    xiaoming.name; // '小明'
    xiaoming.hello(); // Hello, 小明!
    
  • 多个对象共用一个函数(可以节省内存)

    var xiaoming = new Student('小明');
    var xiaohong = new Student('小红');
    xiaoming.hello();
    xiaohong.hello();
    

(2)原型继承

看懵了

(3)class继承

7.浏览器

(1)浏览器对象

(2)操作DOM

<!-- HTML结构 -->
<div id="test-div">
<div class="c-red">
    <p id="test-p">JavaScript</p>
    <p>Java</p>
  </div>
  <div class="c-red c-green">
    <p>Python</p>
    <p>Ruby</p>
    <p>Swift</p>
  </div>
  <div class="c-green">
    <p>Scheme</p>
    <p>Haskell</p>
  </div>
</div>
// 选择<p>JavaScript</p>:
var js = document.getElementById('test-p');

// 选择<p>Python</p>,<p>Ruby</p>,<p>Swift</p>:
var arr = document.getElementById('test-div').getElementsByClassName('c-red c-green')[0].children;

// 选择<p>Haskell</p>:
var haskell = document.getElementsByClassName('c-green')[1].lastElementChild;
  • innerhtml和innertext

    • 1) innerHTML设置或获取标签所包含的HTML+文本信息(从标签起始位置到终止位置全部内容,包括HTML标签,但不包括自身)

    • 2) outerHTML设置或获取标签自身及其所包含的HTML+文本信息(包括自身)

    • 3) innerText设置或获取标签所包含的文本信息(从标签起始位置到终止位置的内容,去除HTML标签,但不包括自身)

    • 4) outerText设置或获取标签自身及其所包含的文本信息(包括自身)

<!-- HTML结构 -->
<div id="test-div">
  <p id="test-js">javascript</p>
  <p>Java</p>
</div>

// 获取<p>javascript</p>节点:
var js = document.getElementById('test-js');

// 修改文本为JavaScript:
// TODO:
js.innerHTML='JavaScript';

// 修改CSS为: color: #ff0000, font-weight: bold
// TODO:
js.style.color='#ff0000';
js.style.fontWeight='bold';
<!-- HTML结构 -->
<p id="js">JavaScript</p>
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>

//修改
var
    js = document.getElementById('js'),
    list = document.getElementById('list');
list.appendChild(js);

//修改后
<!-- HTML结构 -->
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
    <p id="js">JavaScript</p>
</div>

//从零建立一个标签,并放入指定位置
var
    list = document.getElementById('list'),
    haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);

//结果
<!-- HTML结构 -->
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
    <p id="haskell">Haskell</p>
</div>
var parent = document.getElementById('parent');
parent.removeChild(parent.children[0]);
parent.removeChild(parent.children[1]); // <-- 浏览器报错,因为已经删除了children[0],原来的children[1]变成了children[0]

(3)操作表单

  • HTML表单的输入控件主要有以下几种:
    • 文本框,对应的<input type="text">,用于输入文本;
    • 口令框,对应的<input type="password">,用于输入口令;
    • 单选框,对应的<input type="radio">,用于选择一项;
    • 复选框,对应的<input type="checkbox">,用于选择多项;
    • 下拉框,对应的<select>,用于选择一项;
    • 隐藏文本,对应的<input type="hidden">,用户不可见,但表单提交时会把隐藏文本发送到服务器。
<input type="datetime-local" value="2015-07-01T02:03:04">
<input type="color" value="#ff0000">
  • 提交表单

    //通过button的click事件提交表单
    <!-- HTML -->
    <form id="test-form">
        <input type="text" name="test">
        <button type="button" onclick="doSubmitForm()">Submit</button>
    </form>
    
    <script>
    function doSubmitForm() {
        var form = document.getElementById('test-form');
        // 可以在此修改form的input...
        // 提交form:
        form.submit();
    }
    </script>
    
    //响应form本身的onsubmit事件,在提交form的时候做修改
    <!-- HTML -->
    <form id="test-form" onsubmit="return checkForm()">
        <input type="text" name="test">
        <button type="submit">Submit</button>
    </form>
    
    <script>
    function checkForm() {
        var form = document.getElementById('test-form');
        // 可以在此修改form的input...
        // 继续下一步:
        return true;
    }
    </script>
    
  • 对用户密码加密

    <!-- HTML -->
    <form id="login-form" method="post" onsubmit="return checkForm()">
        <input type="text" id="username" name="username">
        <input type="password" id="password" name="password">
        <button type="submit">Submit</button>
    </form>
    
    <script>
    function checkForm() {
        var pwd = document.getElementById('password');
        // 把用户输入的明文变为MD5:
        pwd.value = toMD5(pwd.value);
        // 继续下一步:
        return true;
    }
    </script>
    
    //进阶版
    <!-- HTML -->
    <form id="login-form" method="post" onsubmit="return checkForm()">
        <input type="text" id="username" name="username">
        <input type="password" id="input-password">
        <input type="hidden" id="md5-password" name="password">
        <button type="submit">Submit</button>
    </form>
    
    <script>
    function checkForm() {
        var input_pwd = document.getElementById('input-password');
        var md5_pwd = document.getElementById('md5-password');
        // 把用户输入的明文变为MD5:
        md5_pwd.value = toMD5(input_pwd.value);
        // 继续下一步:
        return true;
    }
    </script>
    

(4)操作文件

  • 可以提交文件的唯一控件为<input type="file">

    • 注意:当一个表单包含<input type="file">时,表单的enctype必须指定为multipart/form-datamethod必须指定为post,浏览器才能正确编码并以multipart/form-data格式发送表单的数据。
  • File API

    • HTML5的File API提供了FileFileReader两个主要对象,可以获得文件信息并读取文件

      var
          fileInput = document.getElementById('test-image-file'),
          info = document.getElementById('test-file-info'),
          preview = document.getElementById('test-image-preview');
      // 监听change事件:
      fileInput.addEventListener('change', function () {
          // 清除背景图片:
          preview.style.backgroundImage = '';
          // 检查文件是否选择:
          if (!fileInput.value) {
              info.innerHTML = '没有选择文件';
              return;
          }
          // 获取File引用:
          var file = fileInput.files[0];
          // 获取File信息:
          info.innerHTML = '文件: ' + file.name + '<br>' +
                           '大小: ' + file.size + '<br>' +
                           '修改: ' + file.lastModifiedDate;
          if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
              alert('不是有效的图片文件!');
              return;
          }
          // 读取文件:
          var reader = new FileReader();
          reader.onload = function(e) {
              var
                  data = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...'            
              preview.style.backgroundImage = 'url(' + data + ')';
          };
          // 以DataURL的形式读取文件:
          reader.readAsDataURL(file);
      });
      

(5)Canvas

  • Canvas是HTML5新增的组件,它就像一块幕布,可以用JavaScript在上面绘制各种图表、动画等。

    没有Canvas的年代,绘图只能借助Flash插件实现,页面不得不用JavaScript和Flash进行交互。有了Canvas,我们就再也不需要Flash了,直接使用JavaScript完成绘制。

    一个Canvas定义了一个指定尺寸的矩形框,在这个范围内我们可以随意绘制:

    <canvas id="test-canvas" width="300" height="200"></canvas>
    

8.JQuery

(1)选择器

按ID查找

// 查找<div id="abc">:
var div = $('#abc')

按tag查找

var ps = $('p'); // 返回所有<p>节点
ps.length; // 数一数页面有多少个<p>节点

按class查找

var a = $('.red'); // 所有节点包含`class="red"`都将返回
// 例如:
// <div class="red">...</div>
// <p class="green red">...</p>

var a = $('.red.green'); // 注意没有空格!
// 符合条件的节点:
// <div class="red green">...</div>
// <div class="blue green red">...</div>

按属性查找

var email = $('[name=email]'); // 找出<??? name="email">
var passwordInput = $('[type=password]'); // 找出<??? type="password">
var a = $('[items="A B"]'); // 找出<??? items="A B">

var icons = $('[name^=icon]'); // 找出所有name属性值以icon开头的DOM
// 例如: name="icon-1", name="icon-2"
var names = $('[name$=with]'); // 找出所有name属性值以with结尾的DOM
// 例如: name="startswith", name="endswith"

使用jQuery选择器分别选出指定元素:

  • 仅选择JavaScript
  • 仅选择Erlang
  • 选择JavaScript和Erlang
  • 选择所有编程语言
  • 选择名字input
  • 选择邮件和名字input
<!-- HTML结构 -->
<div id="test-jquery">
    <p id="para-1" class="color-red">JavaScript</p>
    <p id="para-2" class="color-green">Haskell</p>
    <p class="color-red color-green">Erlang</p>
    <p name="name" class="color-black">Python</p>
    <form class="test-form" target="_blank" action="#0" onsubmit="return false;">
        <legend>注册新用户</legend>
        <fieldset>
            <p><label>名字: <input name="name"></label></p>
            <p><label>邮件: <input name="email"></label></p>
            <p><label>口令: <input name="password" type="password"></label></p>
            <p><button type="submit">注册</button></p>
        </fieldset>
    </form>
</div>
//答案
selected = $("#para-1");
selected = $(".color-red.color-green");
selected = $("#para-1,.color-red.color-green");
selected = $("[class^=color-]");
selected = $("input[name=name]");
selected = $("input[name=name],input[name=email]");
posted @ 2021-04-11 20:30  Dapeus  阅读(74)  评论(0)    收藏  举报