java script1

js的错误分类

语法错误,代码未执行系统就发现错误,出现报错

 function() {

 }
 // Function statements require a function

引用错误,访问一个还未定义的变量会导致这样的错误

 var b="ws"
 alert(b) // ws
 alert(a) // b is not difiend

类型错误,定义的是一个变量,却当作函数调用

var m=234; 
m(); //m is not a function

范围错误,范围指定不当

js异常处理

异常不是错误,异常是指可能会出现错误的代码

try{
    //可能出错的代码
}catch(e){
    // 如果上面代码错误了,就在这里进行错误处理,其中e表示错误对象
    // 它里面包含了错误信息,通过查看e,可以知道出现了什么错误
    // 代码在此处停止,不会向下执行
}finally{
    // 代码作用:无论对错代码都会执行到此处
}

js中的逻辑与(&&)和逻辑或(||)

// 逻辑与(&&),双元运算符  有两个操作数
// 只有两个操作符都为真,整体结果才为真
console.log(true && true); //true
console.log(true && false); //false
console.log(false && true); //false
console.log(false && false); //false
//左结合性,左侧为true时,确定不了整体的结果,遍历到右侧值时,方能确定整体结果
// 左侧为false时,可以直接返回结果为false,代码不再继续执行此行代码

// 逻辑或(||),双元运算符   有两个操作数
// 只要有一个操作数为真,整体的值就为真,两个操作数都为假时,整体结果才为假
console.log(true || true); //true
console.log(true || false); //true
console.log(false || true); //true
console.log(false || false); //true
// || 为左结合性,左侧为true时,直接返回整体结果为true,代码不会继续向下执行
// 左侧为false时,不能直接确定整体的值,需要继续获取第二个操作数,为true时整体结果为true,为false时整体结果为false

// 逻辑非(!),单元(单目)操作符 1个操作符
  如果操作符为真,整体为假,如果操作符为假,整体为真
console.log(!true); // false
console.log(!false); // true
//逻辑运算符的操作数数据类型是布尔值,如果不是布尔值,系统会发生隐式类型转换,将其转换为布尔值
// 0,underfind,空格.. 转换为false
// 第一个操作符能决定整体的值,js就会停止对第二个操作数的运算

let a = 10;
let b = 0;
let c = b && a++; //b为false,确定整体值,a++不执行
let d = a++ && b;
console.log(a); // 11
console.log(b); // 0
console.log(c); // 0
console.log(d); // 0
var a = 0; 
var b = 2; 
var c = a || b++; 
console.log(a); // 0
console.log(b); // 3
console.log(c); // 2

var m = 1; 
var n = ""; 
var q = m || n; 
console.log(m); // 1
console.log(n); // 
console.log(q); // 1

==用与判断是否相等,===判断是否绝等(也会比较类型)

&&和||的优先级

let x = 1 || 2 && 3 || 4 && 0 || 5;
//-------------  3  ----- 0 ------
console.log(x); //1
// &&的优先级大于||的优先级

同步代码与异步代码

同步:代码的书写顺序和代码的执行顺序一样。

异步:代码的书写顺序和代码的执行顺序不一样。

98%代码都是同步代码。
在JS中,异步代码仅仅是个别:
    1)事件绑定
    2)定时器
    3)ajax
    ....
// 页面上每一个盒子本质都是对象
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<script>
    let btns = document.getElementsByTagName("button");
    console.log(btns)
    // 打印出btr的元素,此为同步代码,书写顺序与代码执行顺序一致
    // 异步代码执行顺序与代码书写顺序不一致,需要在特定情况下才会执行,如下代码:只有在浏览器上点击,触发onclick事件代码才会执行。
    btns[0].onclick = function() {
        console.log(0)
    };
    btns[1].onclick = function() {
        console.log(1);
    };
    btns[2].onclick = function() {
        console.log(2)
    };
</script>

this总结

如果this出现在普通的函数中,this表示window,如果通过window打点调用一个函数,这个函数中的this也是window。

事件绑定,事件处理程序,事件发生时浏览器帮助我们调用这个函数,函数中的this事件源

在一个对象中,如果有方法(函数),如果通过这个对象调用方法,方法中的this表示这个对象

在IIFE(立即执行函数)中,this表示window

call / apply /bind 的使用

call / apply /bind 都可以修改this的指向

为什么要修改this的指向,如下代码:

下面两个对象中有两个同样的方法,占用了两个堆空间

var obj1 = {name:"wc", say:function (){alert("我是"+this.name)}}
var obj2 = {name:"zs", say:function (){alert("我是"+this.name)}}
obj1.say(); 
obj2.say(); 

//改进方法1
let abc = function (){alert("我是"+this.name)}
var obj1 = {name:"wc",say:abc}
var obj2 = {name:"zs",say:abc}
obj1.say();
obj2.say();
//改进方法2
let abc = function (){alert("我是"+this.name)}
var obj1 = {name:"wc", say:abc}
var obj2 = {name:"zs", say:abc}
abc.call(obj1); 
abc.call(obj2)

更精确的检测数据类型

用typeof检测基本数据类型时没有问题,但是检测引用数据类型时,会出现小差错

console.log(typeof 1) // number
console.log(typeof "hello") // string
console.log(typeof true) // boolean 

var a;
console.log(typeof a)  // undefined  
console.log(typeof [1,2,3])  // object  
console.log(typeof {a:1})  // object  
let d = new Date();
console.log(typeof d)  // object  
let r = new RegExp()
console.log(typeof r)  // object  
function f(){}
console.log(typeof f)  // function  

利用Object.prototype.toString.call可以非常精确地检测一个数据的数据类型


    function getType(abc) {
        var rs = Object.prototype.toString.call(abc);
        rs = rs.substr(8) // substr(数据的截取),substr(number,length),开始位置,截取数据的长度,如果不写的话,后面截取完
        var len = rs.length
        return rs.substr(0,len-1).toLowerCase() //转小写
    }
    console.log(getType(123)); //number
    console.log(getType([])); // object
    console.log(getType({})); //function
    console.log(getType(new Date));  //date
    console.log(getType(new RegExp)); // regexp
    var f = function(){}
    console.log(getType(f)); // function

字符串翻转

方法1

var str = "123456"
var newStr = "";
for(var i = str.length-1;i>0;i--){
    newStr += str[i];
}

方法2

//reverse数组中翻转属性
ver arr = [1, 2, 3]
alert(arr.reverse()); // [3, 2, 1]
// 字符串翻转,让字符串变成数组
var str = "123"; 
alert(str.split("")); // ["1", "2", "3"]
alert(str.split("").reverse()); //["3", "2", "1"]
alert(str.split("").reverse().join("")) // 321
// call指向
alert(Array.prototype.reverse.call(str.split("")).join("")); // 321

call / apply /bind 的区别

bind:绑定的意思,改变了this的指向,函数不执行

function F(a, b) {
console.log("F...")
    return a+b;
}
var obj = {};
let k = F.bind(obj)
console.log(k(1, 2));;

call: 改变了this的指向,并让函数执行,传递参数一个一个传递

function F(a,b) {
    console.log("F...");   // F..
    return a+b;
}
var obj = {};
console.log(F.call(obj,1,2)); // 让obj借用函数F    3

apply: 改变了this的指向,并让函数立即执行,传递参数必须为数组

function F(a, b) {

    console.log("F..."); // F...
    return a+b;

}
var obj = {}; 
console.log(F.apply(obj, [1, 2])); //让obj借用函数F  3 

伪数组

长的像数组 但不是真正的数组
真正的数组:[“a”,“b”,“c”]
伪数组 {0:“a”,1:“b”,2:“c”} 本质是对象

伪数组中有没有数组原型对象上的方法?

答:没有 本质是对象

常见的伪数组:

  1. 通过document.getElementsByTagName获取的元素集合就是伪数组
  2. 函数内部的arguments

初识面向对象

常见思想

面向过程:C语言

面向对象:JAVA,C++,JS(基于对象)

面向切面:Spring,IOC,AOP

面向对象特征:

抽象:具体问题抽象化
封装:把属性和方法封装到类中
继承:父对象中的成员,子对象无需重复创建,就可以直接访问。
多态:

对象

对象是属性的无序集合
访问对象中属性的方法, 1)打点调用;2)通过[]来调用

var obj = {
    name:"wc"; //前面为属性名(键),后面为属性值(键值)
    age:16;
    "1+1":2;
}
console.log(obj.name);
console.log(obj.age);
console.log(obj["1+1"]);
//如果键是一个变量,我们需要通过变量去访问 ,必须使用[].

操作对象中的属性之遍历对象

通常使用for-in来遍历对象

var obj = {

    name:"wangcai";
    age:12;
    say:function(){
        console.log("say...")
    }

}
for(var a in obj){

    console.log(a+":"+obj[a]);

}

对象中属性的四大特征

  1. configurable :表示能否通过delete删除属性,true表示可以删除
  2. writable :表示能否修改属性的值,true表示能修改
  3. enumerable :是否能通过for-in循环返回属性,true表示可以
  4. value :包含这个属性的数据值

通过Object.getOwnPropertyDescriptor获取修改属性的特征

let obj = {
    name:"wc"
}
console.log(Obj.getOwnPropertyDescriptor(obj,"name"))
// configurable: false;
// enumerable :true;
// writable :true;
//value :wc

给一个对象添加属性时,也可以设置这四个特征;此方法接受三个参数,属性所在对象,属性名,描述符对象

var obj = {};
Object.defineProperty(obj,"name",{
       configurable:false,
       writable:false,
       enmerable:true,
       value:"wangcai"
})
 

属性的分类

对象上的属性分两类

  1. 私有属性
  2. 公有属性

通过hasOwnProperty()可以查看一个属性是否有私有属性
in是一个运算符,用于判断一个属性是否属于某个对象(“c” in obj)

var obj = {

    name:"wangc"
    age:89;

}
console.log(obj.hasOwnProperty("toString")); // false
//delete只能删除私有属性,不能删除公有属性
//如果一个私有属性和公有属性重名了 会把公有属性盖掉

对象是由函数创造的

在JS中函数有多个角色

  1. 普通函数
  2. 类 构造器
  3. 对象
  4. 对象中的一个方法

构造器的本质是函数

任何对象中都有一个属性__proto__, 此属性也是一个对象

对象中都有一个属性叫 constructor 是构造器

对象是由函数创建的/对象是由构造器构成的

构造器的本质是函数

原型和原型链

每一个对象上都有一个属性叫__proto__ 为隐式原型

每一个构造器(函数)上都有一个属性叫prototype 它叫原型是一个对象,这个对象我们叫做原型对象

JS中的继承

继承:子类可以去继承父类的公有属性和私有属性
将子类原型对象地址指向父类
特点:可以继承父类的公有属性和私有属性

普通函数继承

//主要代码: Child.prototype = new Parent;
function Parent() {
    this = 100;
}
Parent.prototype.getX = function (){ //Parent的公有属性
    return this.x;
}
function Chid(){
    this.y = 200
}
Chid.prototype = new Parent; //将Chid的原型对象地址更换为Parent子类对象的地址
Chid.prototype.getY = function(){
    return this.y  // 向Chid的原型对象中加入方法
}
var c1 = new Chid;
console.log(c1.x); //100,继承了父类的x;
console.log(c1.getX());//100,继承了父类的getX方法;
console.log(c1.y);  //200,创建对象时this赋值;
console.log(c1.getY);//200,引用父类Chid的getY方法;

call继承

特点:只能继承父类的私有属性
主要代码:Parent.call(this) – 将Parent中的this指针指向子类新建对象的地址

function Parent(){  //创建一个构造器

    this.x = 100;

}
Parent.prototype.getX = function(){ //向构造器的公有属性中加入一个方法

    return this.x;  

}
function Chid(){ //创建一个新的构造器;

    Parent.call(this);//让上一个构造器的this指针,指向这个新的构造器的this指针指向的地址
    this.y = 200;

}
var c1 = new Chid; //以Chid构造器创建一个对象,
console.log(c1.x); //100, 此对象中有x,y私有属性,一个继承自Parent,一个继承自Chid

组合式继承

// 1)Parent.call(this);继承父类的私有属性
// 2)Chid.protype = Object.create(Parent.prototype);继承父类的公有属性
function Parent(){
    this.x = 100;
}
Parent.prototype.getX = function () { 
    return this.x;
}
function Child() {
    Parent.call(this);
    this.y = 200;
}
//Child.prototype = Parent.prototype//用此代码也可以继承Parent的公有属性,但是改变了Child.prototype的地址指向了Parent.prototype,向Child添加公有属性时,也会影响到Parent公有属性的内容
Child.prototype = Object.create(Parent.prototype);
var c = new Child();
console.log(c.x);
console.log(c.getX())

ES6中的继承

super(); //类似前面的call继承,继承私有属性
extends //类似于原型对象,继承公有属性

class Parent{
    constructor(){
        this.x = 100;
    }
    getX(){
        return this.x;
    }
}
class Child extends Parent{
    constructor(){
        super();
        this.y = 200;
    }
    getY(){
        return this.y
    }
}
var chid = new Child();
console.log(child.x);
console.log(child.get());

创建对象的方法

字面量创建对象

var rect = {
    width:10;
    height:20;
    getS(){
        return this.width+this.height;
    }
}
//需要一个矩形对象还要手动添加进去;
rect.getC = function(){
    return 2*this.width + 2*this.height;
}
console.log(rect.getS());//200
console.log(rect.getC());//60

工厂模式创建对象

function creatRect(w,h){
    var obj = {};
    obj.width = w;
    obj.height = h;
    obj.getS = function(){
        return this.width*this.height;
    }
    return obj
}
var rect1 =creatRect(2,4);
console.log(rect1.getS());
var rect2 = creatRect(2,2);
console.log(rect2.getS());

构造器创建对象

构造器+原型创建对象

ES6创建对象
return this.width+this.height;
}
}
//需要一个矩形对象还要手动添加进去;
rect.getC = function(){
return 2this.width + 2this.height;
}
console.log(rect.getS());//200
console.log(rect.getC());//60


**工厂模式创建对象**
```java script
function creatRect(w,h){
    var obj = {};
    obj.width = w;
    obj.height = h;
    obj.getS = function(){
        return this.width*this.height;
    }
    return obj
}
var rect1 =creatRect(2,4);
console.log(rect1.getS());
var rect2 = creatRect(2,2);
console.log(rect2.getS());

构造器创建对象

构造器+原型创建对象

ES6创建对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值