
客户端脚本语言的标准
内部JS:
标签体内容就是js代码
<script text="text/javascript">// 内容
</script>
外部JS:
通过src属性引入外部的js文件
<script text="text/javascript" src="location">// 内容
</script>
注意:
数字类型,整数 / 小数 / NaN(not a number 一个不是数字的数字类型)
toFixed(x) 小数点后保留 x 位小数
问题 bug:
浮点数精度不准
console.log(0.14 * 100); // 14.000000000000002
小数点前 以及 小数点后 位数大于 16 会出现精度问题
console.log(1000000000000001 + 1000000000000001) // 2000000000000002
console.log(10000000000000001 + 10000000000000001) // 20000000000000000console.log(1.000000000000001 + 1.000000000000001) // 2.000000000000002
console.log(1.0000000000000001 + 1.0000000000000001) // 2
字符串类型,字符串 “abc” “a” ‘abc’
布尔类型,true 和 false
存放在 栈 里,规则 先进后出
Array:数组。
Object:对象。
function:函数。
…
存放在 堆 里,拷贝的是地址
一小块存储数据的内存空间
Java语言是强类型语言,而JavaScript是弱类型语言。
访问规则
var 变量名 = 初始化值;// 定义多个遍历并赋值
var a = 10,b = 20,c = 30,d = 40,e;
document.write(a,b,c,d,e);
获取变量的类型。
number string boolean object undefined function
console.log(typeof(123)); // number
console.log(typeof("123")); // string
console.log(typeof(true)); // boolean
用法:
typeof(值)typeof 值注:
null、array 运算后得到的是object
typeof() 返回的值是字符串类型
console.log(typeof(typeof(a))); // string
特殊:
变量不定义就使用必定会报错,只有一种情况下不会
console.log(typeof(a)); // undefined
自定义 type 方法:区分所有类别
function type(target) {var ret = typeof(target);var template = {"[object Array]" : "array","[object Object]" : "object","[object Number]" : "number - object","[object Boolean]" : "boolean - object","[object String]" : "string - object"}if (target === null) {return "null";} else if (ret == "object") {var str = String.call(target);return template[str];} else {return ret;}
}
console.log(isNaN(NaN)); // true
console.log(isNaN(123)); // false
console.log(isNaN("123")); // false
console.log(isNaN("abc")); // true
console.log(isNaN(null)); // false
console.log(isNaN(undefined)); // true
isNaN() 之前会先 Number()
模拟 isNaN() 方法:
function myIsNaN(num) {var ret = Number(num);ret += "";if (ret == "NaN") {return true;} else {return false;}
}
(自增 自减 正负号)
var a = "123";
a ++; // 124
var a = +"123"; // +123
var b = +"abc"; // NaN
(加号)
两侧没有字符串,则正常数字相加,调用 Number() 方法将不是 number 的隐式转换
当加号两侧至少有一侧是字符串时,会调用 String() 方法把两侧均转换为字符串
当加号左侧是引用类型值时,调用的是 String() 方法隐式转换
[] + 1; // --> String([]) + 1 --> "1"
[] + ""; // ""
{} + 1; // 1
但引用值的隐式类型转换不用知道,规则较多。
(运算符号)
调用 Number() 方法
var num = "2" * "1"; // number : 2
var num = "a" * "1"; // number : NaN
[] - 1; // -1
判断调用 Boolean() 方法
(比较符号)
var a = 3 > "2"; // boolean: true
var a = "3" > "2"; // 会比较对应的 ASCII码 值
特殊
undefined > 0; // false 不转换,系统规定 undefined 和 null 不能和数进行比较
null > 0; // false
调用 Boolean() 方法
var a = 1 == true; // boolean: true
引用值比较的是地址:
{} == {}; // false
[] == []; // falsevar obj = {};
var obj1 = obj;
obj == obj1; // true
obj === obj1; // true
特殊:
undefined == null; // true
NaN == NaN; // false
把里面的东西转换为数字型
null false => 0
undefined => NaN
把里面的数转换为整数
注:看到非数字位截止
parseInt("123"); // 123
parseInt("123abc"); // 123
// 用途
// 把像素值从 100px 中取出来
parseInt(值, radix) radix: 2 - 36
后面的第二个参数表示此数所表示的进制
parseInt("B", 16); // 11
后面填 0
注:看到除了第一个 . 的非数字位截止
parseFloat("123.12abc"); // 123.12
语法:
var demo = 10
var str = String(); // "10
// 转换进制
var num = String(8); // 12
注:undefined 和 null 不能用 toSting() 方法
例子:
二进制 转 十六进制
var num = 10000;
var test = parseInt(num, 2);
console.String(16)); // aa
数值 和 类型 均相等才可
1 === 1; // true
1 === "1"; // false
1 !== "1"; // true
1 !== 1; // false
特殊:
NaN === NaN; // false
var str = false + 1;
document.write(str); // 1
var demo = false == 1;
document.write(demo); // false
if (typeof(a) && -true + (+undefined) + "") {document.write('基础扎实!');
}
if (11 + "11" * 2 == 33) {document.write('基础扎实!');
}
!!" " + !!"" - !!false || document.write('你觉得能打印,你就是🐖');
只有一个运算数的运算符
++,-- , +(正号)
注意:在JS中,如果运算数不是运算符所要求的类型,那么js引擎会自动的将运算数进行类型转换
+ - * / %
注:
= += -= *= /= %=
< >= <= == ===(全等于)
比较方式:
类型相同:直接比较
字符串:按照字典顺序比较。按位逐一比较,直到得出大小为止。即 ASCII码 值
类型不同:先进行类型转换,再比较
===:全等于。在比较之前,先判断类型,如果类型不一样,则直接返回false
&& || !
&&(与):先看第一个表达式转化为 boolean 值是否为真,结果为真,则依次往后看每个表达式转换为boolean值的结果,直到碰到结果为 false 的表达式,返回该表达式的值。
用法:(短路语句)
var data = ...;
// data && 执行一个语句,会用到data;
data && fn(data);
||(或):碰到表达式的结果 boolean值为真则返回该表达式的值
用法:(兼容)
lick = function (e) {// 兼容 IE 浏览器var event = e || window.event;
}
! (非):将表达式的值转换为 boolean值 再取反,返回该 boolean值。
var a = !!"";
// !! 可以让一个值转换为 boolean值
注意:
undefined、null、NaN、""、0、false ==> false
除了以上六个值以外,其他的转换为 boolean 类型均为 true
练习:
(window.foo || (window.foo = 'bar'));
// window.foo = 'bar'
// 先读小括号内的,即先赋值
语法:
表达式 ? 值1 : 值2;
判断表达式的值,如果是 true 则取值1,如果是 false 则取值2;
会将后面的结果返回出去
var a = (1 - 1, 1 + 1);
a --> 2
优先运算
将里面的内容变为表达式
(function () {}) 函数声明失效,变为表达式
立即执行
(function () {})()
if…else…
if(判断语句) {条件体
}
switch:
在java中,switch语句可以接受的数据类型: byte int shor char,枚举(1.5) ,String(1.7)
在JS中,switch语句可以接受任意的原始数据类型
switch () {case 判断条件1:执行语句1; break;case 判断条件2:执行语句2; break;case 判断条件3:执行语句3; break;...default:break;
}
while
底层机制就是 for 循环:for 循环括号内两边不写语句就是 while 循环:for (;条件语句;) {}
while(条件语句) {循环语句
}
do…while
先执行一次,再判断条件语句
do {循环体
} while (条件语句)
for
break
跳出循环或者 switch
continue
终止本次循环进行下次循环
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>99乘法表</title><style>td{border: 1px solid;}</style><script>document.write("<table align='center'>");//1.完成基本的for循环嵌套,展示乘法表for (var i = 1; i <= 9 ; i++) {document.write("<tr>");for (var j = 1; j <=i ; j++) {document.write("<td>");//输出 1 * 1 = 1document.write(i + " * " + j + " = " + ( i*j) +" ");document.write("</td>");}/*//输出换行
document.write("<br>");*/document.write("</tr>");}//2.完成表格嵌套document.write("</table>");</script></head><body></body>
</html>
使用包装类对象创建的以下三种对象,依然还带有原本的数据类型的特点,不同在于可以有属性和方法
但是 undefined 和 null 不可以设置属性
var num = new Number(123);
var str = new Stirng('abcd');
var bol = new Boolean('true');
原始数据类型不能有自己的属性和方法
但下面这个却不报错:
var num = 4;
num.len = 3; // 不报错
console.log(num.len) // undefined
原因:(包装类)
var num = 4;
num.len = 3; // 不报错
// new Number(4).len = 3;
// delete
// new Number(4).len --> undefined
console.log(num.len) // undefined
在数组中:
var arr = [1, 2, 3, 4, 5];
// arr.length --> 5
arr.length = 2
// arr.length --> 2
// arr --> [1, 2]
但是,在字符串中
var str = 'abcd';
// str.length --> 4
str.length = 2;
// new String('abcd').length = 2;
// delete
console.log(str); // abcd
// new String('abcd').length
console.log(str.length); // 4
字符串对象 本身就有 length属性,调用时是从包装类对象中返回的属性值
var str = 'abc';
str += 1;
var test = typeof str; // test --> 'string'
if (test.length == 6) {test.sign = 'typeof的返回结果可能为String';// new String(test).sign = 'xxx';
}
// new String(test).sign
console.log(test.sign);
高内聚,弱耦合
var fn = new Function(形式参数列表,方法体);//忘掉吧// 函数声明
function 方法名称(形式参数列表) {方法体
}// 命名函数表达式
var 方法名 = function abc() {方法体
}
// 匿名函数表达式 --- 函数表达式
var 方法名 = function() {方法体
}
// 形式参数(形参)
function sum(a, b) {var c = a + b;document.write(c);
}
// 实际参数(实参)
sum(1, 2); // 3
参数不限制位数
表示实参列表,也有一些属性
arguments.length 实参个数
arguments.callee 指向这个函数自身引用 --> 即函数本身
var num = (function (n) {if (n == 1) {return 1;}return n * arguments.callee(n - 1);
}(100))
函数名.length 形参个数
function sum(a) {// arguments -- [11,2,3] 实参列表console.log(arguments); // [11,2,3]console.log(arguments.length); // 3// 函数名.length -- 形参长度concole.log(sum.length); // 1
}
sum(11, 2,3)
例子:
// 求不定参数个数的和
function sum() {var result = 0for (let i = 0; i < arguments.length; i++) {result += arguments[i];}document.write(result);
}
sum(1,3);
arguments里面的值 和 形参的值 之间有映射关系,但只是在形参和实参对应时才生效
function sum(a, b) {// arguments --> [1]a = 2;console.log(arguments[0]); // 2arguments[0] = 3;console.log(a); // 3b = 2;console.log(arguments[1]); // undefined
}
sum(1);
函数的一个属性:表示被调用的环境
function test() {demo();
}
function demo() {demo,caller; // --> test --> function test() {demo();}
}
test();
不怎么用,但会和 arguments.callee 一块出现做区分
方法名称(实际参数列表);
模拟 jQuery 连续调用
var deng = {smoke : function () {console.log(');return this;},drink : function () {console.log(');return this;},perm : function () {console.log(');return this;}
}deng.smoke().drink().perm();
function myNumber(target) {return +target;
}
var num = myNumber('123');
console.log(typeof(num) + " " + num); // number 123
// 求阶乘方法
// n! = n * (n-1)!
function mul(n) {if (n == 1 || n == 0) {return 1}return n * mul(n - 1);
}
var n = parseInt(prompt('input'));
mul(n);
// 递归
/* mul(5);5 * mul(4);5 * 4 * mul(3);5 * 4 * 3 * mul(2);5 * 4 * 3 * 2 * 1;
*/
// 斐波那契数列
// fb(n) == fb(n - 1) + fb(n - 2)
function fb(n) {if (n == 2 || n == 1) {return 1;}return fb(n - 1) + fb(n - 2);
}
原型是 function 对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该圆心的属性和方法。原型也是对象。
Person.prototype.LastName = "Agoni";
function Person() {}
var person = new Person();
var person1 = new Person();
// person.LastName --> "Agoni"
// person1.LastName --> "Agoni"
对象中固定不变的属性(公有的内容)可以提取出来放到原型中,避免代码多次执行造成冗余。
删
delete Person.prototype.LastName;
经过了 var 给 window 上增加的属性为不可配置性属性,delete无法删除。
增改查
Person.prototype.LastName = "Agoni";
设置属性(可以多个一起设置)
Person.prototype = {height: 1400,lang, 4900,carName: "BMW"
}
和 Person.prototype.name = "" 的区别:
__proto__ 所指向的还是原先的那个空间;__proto__ 的访问数据变更function Car() {}
var car = new Car();
// structor --> funciton Car() {}function Person() {}
Car.prototype = {constructor : Person
}
// structor --> function Person() {}
隐式属性 __proto__ 内就放着原型,在控制台展开可以查看
原理:
Person.prototype.name = "abc";
funciton Person() {// var this = {// __proto__ : Person.prototype// }
}
var person = new Person();
原型也可以改变:
// 代码接上一部分
var obj = {name: "sunny"
}
var person = new Person();
// person.name --> "abc"
Person.__proto__ = obj;
// person.name --> "sunny"
Grand.prototype.lastName = "agoni";
funciton Grand() {}
var grand = new Grand();Father.prototype = grand;
function Father() {this.name = "Lay"
}
var father = new Father();Son.prototype = fatehr;
function Son() {this.hobbit = "smoke"
}
var son = new Son();
// son.hobbit --> "smoke"
// son.name --> "Lay"
// son.lastName --> "Agoni"
查找属性,依照 son --> father --> grand 顺序依次查找,这个链就叫 原型链。
链顶并不是最末的:
是绝大多数对象的最终原型
// Grand.prototype.__proto__ --> Object.prototype// String() --> function toString() { [native code] } // 最终终端的方法// Object.prototype.__proto__ --> null
Object.prototype 里面没有 __proto__ 了
括号内填原型:只能是 对象 或 null
Person.prototype.name = "sunny";
function Person() {}
var person = ate(Person.prototype)
特殊点:
原型最终不会指向 Object.prototype
var obj = ate(null);
// String() --> 访问不到,报错
语法:
Person.prototype = {toString : function () {return 'hehe';}
}
function Person() {}
var person = new Person();
// String(); --> "hehe"
发生截断,不会访问到终端 Object.prototype 的 toSting() 方法
Number Array Boolean String 都对 toSting() 方法进行了重写
会隐式调用 toSting() 方法
var obj = ate(null);
document.write(obj); // 报错,因为自己创建的对象值为 null 且 ate() 创建的没有原型链,没有 toString() 方法,所以报错Stirng = function () {return 'AgoniLay';
}
document.write(obj); // AgoniLay --> 调用了 AgoniLay 方法
test(); // --> test.call();
call 带参数
根本作用:改变 tihs 指向
function Person(name, age) {this.name = name;this.age = age;
}
var person = new Person('deng', 100);var obj = {}
// 第一个参数指 this 的指向,之后的依次代表 实参 对应 形参
Person.call(obj, 'agoni', 19);
// obj --> {name: 'agoni', age: 19}
使用实例:
function Person(name, age, sex) {this.name = name;this.age = age;this.sex = sex;
}
function Student(name, age, sex, tel, grade) {Person.call(this, name, age, sex);l = ade = grade;
}var student = new Student('sunny', 123, 'male', 1309, 2017);
function Wheel(wheelSize, style) {this.style = style;this.wheelSize = wheelSize;
}
function Sit(c, sitColor) {this.c = c;this.sitColor = sitColor;
}
function Model(height, width, len) {this.height = height;this.width = width;this.len = len;
}
function Car(wheelSize, style, c, sitColor, height, width, len) {Wheel.call(this, wheelSize, style);Sit.call(this, c, sitColor);Model.call(this, height, width, len);
}
var car = new Car(100, '花里胡哨', '真皮', 'red', 1800, 1900, 4900);
// car {style: "花里胡哨", wheelSize: 100, c: "真皮", sitColor: "red", height: 1800, …}
和 call() 区别:
function Car(wheelSize, style, c, sitColor, height, width, len) {Wheel.apply(this, [wheelSize, style]);Sit.call(this, [c, sitColor]);Model.call(this, [height, width, len]);
}
传统形式 --> 原型链
借用构造函数 call()/apply()
共享原型
son.prototype = father.prototype
Father.prototype.lastName = "AgoniLay"
function Father() {
}
function Son() {
}
funciton inherit(Target, Origin) {Target.prototype = Origin.prototype;
}
// 先继承,后用
inherit(Son, Father);var son = new Son();
// son.lastName --> "AgoniLay"
// father.lastName --> "AgoniLay"Son.prototype.sex = "male"; // 添加后,son 和 father 都有了这个属性
// son.sex --> "male"
// father.sex --> "male"
圣杯模式 *
// 通俗写法
function inherit(Target, Origin) {function F() {};// 以下两行顺序不能颠倒F.prototype = Origin.prototype;Target.prototype = new F();// 优化stuctor = Target;Target.prototype.uber = Origin.prototype;
}Father.prototype.lastName = "AgoniLay"
function Father() {
}
function Son() {
}inherit(Son, Father);
var son = new Son();
var father = new Father();
// father.lastName --> "AgoniLay"
// son.lastName --> "AgoniLay"Son.prototype.sex = "male";
// son.sex --> "male"
// father.sex --> undifined
// 雅虎的
var inherit = (function () {var F = function () {}; // 闭包应用 -- 私有化变量return function (Target, Origin) {F.prototype = Origin.prototype;Target.prototype = new F();structor = Target;Target.prototype.uber = Origin.prototype;}
}());
var arr = []; 数组字面量 – 推荐使用
var arr = [1,2,3];var arr = [,,]; // [undefined * 2]
var arr = [1,,2]; // [1, undefined, 2] --> 稀松数组
var arr = new Array();
var arr = new Array(1,2,3,4,5);
和 数组字面量 区别:
// 只传一个参数,代表数组的长度
var arr = new Array(10); // [undefined * 10]
// 但不能只传一个小数
var arr = new Array(10.2); // 报错
溢出读是 undefined,可以溢出写
var arr[1,2,3];
arr[0] = 2 // [2,2,3]
console.log(arr[10]); // undefined 不会报错
arr[10] = "aa"; // 可以添加 --> [1,2,3,undefined * 7,"aa"]
可以改变原数组的方法开始:只有七个
在数组最后添加数据,不仅可以添加一个,返回值是添加后的数组长度
// 自己写 push() 方法
var arr = [];
Array.prototype.push = function () {for(var i = 0; i < arguments.length; i ++) {this[this.length] = arguments[i];}return this.length;
}
arr.push(1,2,3); // 3 --> [1,2,3]
但 push 的原理是取决于属性中 length 值,与 length 值有关
把数组的最后一位剪切出来返回
在数组开头添加数据,不仅可以添加一个,返回值是添加后的数组长度
把数组的第一位剪切出来返回
把数组逆转,把原数组返回
arr.splice(从第几位开始, 截取多少的长度, 在切口处添加新的数据)
返回截取的数组
var arr = [1,1,2,2,3,3];
arr.splice(1,2); // [1,2] --> [1,2,3,3]var arr = [1,1,2,2,3,3];
arr.splice(1,2,0,0,0) // [1,2] --> [1,0,0,0,2,3,3]var arr = [1,2,3,4];
// 不截取,只是向中间插入数据 例:向上面数组 3 后面添加一个 0
arr.splice(3,0,0);var arr = [1,2,3,4];
// 截取的位置可以是负数,表示从倒数开始
arr.splice(-1,1); // [4] --> [1,2,3]
// 实现
splice = function (pos, ...) {pos += pos > 0 ? 0 : this.length; // -1 + 4 = 3
}
在原数组上将原数组内元素升序排列(但并不是数字值的大小)
var arr = [1,3,4,0,-1,9];
arr.sort(); // [-1,0,1,3,4,9]
// 降序
arr.sort().reverse();
为了解决这个问题,sort 留了一个接口让用户自定义排序方式
规则:
var arr = [1,3,5,4,10];
// 传参顺序 1,3 1,5 1,4 1,10 3,5
arr.sort(function (a, b) {// 函数体// if (a > b) {// return 1;//} else {// return -1;//}// 简化return a - b; // 升序// return b - a; // 降序
}) // [1, 3, 4, 5, 10]
运用:
给一个有序的数组,乱序
var arr = [1,2,3,4,5,6,7];
arr.sort(function () {return Math.random() - 0.5;
})
给一个对象数组,按某一属性排
var cheng = {name : "cheng",age : 30,
}
var deng = {name : "deng",age : 60,
}
var zhang = {name : "zhang",age : 19,
}
var arr = [cheng, deng, zhang];
// 按年龄升序排列
arr.sort(function (a, b) {return a.age - b.age;
}) // ["zhang", "cheng", "deng"]
按字符串长度排序
var arr = ['as', 'asdad', 's', 'sjdfhakjsdfhlkajsd', 'asdjhajsk'];
arr.sort(function (a, b) {return a.length - b.length;
}) // ['s', 'as', 'asdad', 'asdjhajsk', 'sjdfhakjsdfhlkajsd']
按字节长度排序
function retBytes(str) {var num = str.length;for(var i = 0; i < str.length; i ++) {if (str.charCodeAt(i) > 255) {num++;}}return num++;
}var arr = ['赛的环境asdj', 'asd', '啥的, 爱睡觉的', 'a saa'];
arr.sort(function (a, b) {return retBytes(a) - retBytes(b);
}) // ["asd", "a saa", "赛的环境asdj", "啥的, 爱睡觉的"]
不改变原数组的方法开始:调用完使用 变量 接收,否则没有意义
把括号内的数组拼接到前面数组的后面,不在原数组上修改,返回拼接后的数组
将数组返回为字符串类型的字符串
arr.slice('从该位开始截取', '截取到该位')
arr.slice(1) 从第 1 位截取,截取到最后,也可以填负数(规则 + length)
arr.slice() 整个截取
将数组中元素按规定连接起来,返回一个字符串
参数可以传所有原始值,但最好传字符串
var arr = [1,2,3];
arr.join("&"); // "1&2&3"
arr.join(); // "1,2,3"
是字符串的方法,是 join() 的可逆方法
var str = "1-2-3-4-5";
str.split("-"); // ["1", "2", "3", "4", "5"]
自定义方法:
Array.prototype.unique = function (arr) {var temp = {};var arr = [];var len = this.length;for (var i = 0; i < len; i++) {if (!temp[this[i]]) {temp[this[i]] = 'agoni';arr.push(this[i]);}}return arr;
}
类数组有要求:
本文发布于:2024-03-10 05:03:24,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/1710346710137882.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
| 留言与评论(共有 0 条评论) |