JS-This判断归属

js函数中this取何值,只有在函数调用时才确定的,定义的时候确定不了,因为this属于执行上下文环境中的一部分,而执行上下文环境在函数每次调用的时候可能都不一样

情况1:new Function() 和普通调用

当一个函数作为构造函数使用时,函数执行时,this为new出来的对象。严格的说所有的函数都可以用作构造函数,都可以new出一个对象

  function Test() {
      this.name = "lly"
      this.age = 27;
      console.log(this);//Test{name:"lly", age: 27}
  }

  let obj = new Test();

此处this仅在new Test()情况下适用,当被当做普通函数使用时,则按下面的情况分析

情况2:作为对象属性和对象属性赋值给别的对象(包括window)情况

(1).当作为对象的属性,且被该对象调用时,则this为该对象

(2).当把该对象的属性赋值给了其他对象,则this为该调用的对象

    let x = 20;
    let obj1 = {
        "x": 100,
         "fn": function () {
              console.log(this);
              console.log(this.x);
          }
    }

    let obj2: any = {
        "x": 200
    };

    obj2.fn = obj1.fn;
    let fn = obj1.fn;

    obj1.fn();//obj1, 100
    obj2.fn();//obj2, 200
    fn(); //window, 20

情况3:函数使用call,aplay

使用这两种方式调用的函数,this为传入的第一个参数指向的内存,call后面的参数列表(一一填入),而aplay后面的参数为数组

let obj = {
    "x" : 10
}

let fn = function(){
    console.log(this);//obj 
    console.log(this.x);//10
}

fn.call(obj,p1,p2,p3);或者fn.aplay(obj,[p1,p2,p3])

情况4:全局函数,包括在函数内创建的函数(也是全局函数)

原来错误理解:原以为在函数1内创建的函数2,使用函数2时,this必为函数1中的this

1.在对象函数中定义的函数,并不属于该对象的属性(使用obj.fun报错,因为不是),所以该函数运行时this并非就是该对象(情况2也有可能不是该对象),具体看怎么调用,如果使用bind,或aplay那没得说

2.如果不是对象中的函数,又没有bind,aplay,也没有把该函数赋值给谁(情况2otherObj.fun = fun  otherObj.fun()),则该函数中的this应该是window(隐式的window.)

3.总结情况4,不是对象中的属性函数,属于全局函数,调用时再能确定,赋值给哪个对象this就是哪个对象,如果没有赋值,则为window

 

情况2图解:解析为何当obj1的函数赋值给了obj2之后,this是obj2,函数在堆中有自己的内存,obj1.fn只是obj1调用了该内存,此时this为obj1,当obj2.fn是用obj2调用了该内存,所以this为obj2()

总结:谁使用了该函数内存,this就是谁,如果没有obj.fn的,则this皆为window

 

<template> <!-- 编辑流量计 --> <div class="edit-flow-meter"> <myModal :params="{ title: '编辑流量计' }" :visible="visible" @submit="submit" @cancel="handleCancel"> <template v-slot:header> <span></span> </template> <template v-slot:body> <div class="edit-flow-meter-box"> <a-form-model ref="baseInfoForm" :model="formData" :rules="rules" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }" > <h4 style="margin: 16px 0; text-align: left">{{ $t('基础信息') }}</h4> <a-row> <a-col :span="12"> <a-form-model-item :label="$t('探测器名称')" prop="detectorName"> <a-input v-model="formData.detectorName" disabled /> </a-form-model-item> </a-col> <a-col :span="12"> <a-form-model-item :label="$t('探测器编号')" prop="uniqueCode"> <a-input v-model="formData.uniqueCode" disabled /> </a-form-model-item> </a-col> <a-col :span="12"> <a-form-model-item :label="$t('流量计编号')" prop="meterCode"> <a-input v-model="formData.meterCode" disabled /> </a-form-model-item> </a-col> <a-col :span="12"> <a-form-model-item :label="$t('接入时间')" prop="rate"> <a-date-picker v-model="formData.rate" show-time format="YYYY-MM-DD HH:mm:ss" :placeholder="$t('请选择接入时间')" /> </a-form-model-item> </a-col> <a-col :span="12"> <a-form-model-item :label="$t('归属')" prop="belonging"> <a-input v-model="formData.belonging" disabled /> </a-form-model-item> </a-col> </a-row> <div class="table-title-box"> <h4 style="margin: 0">{{ $t('子流量计列表') }}</h4> <div style="display: flex"> <a-button class="mgr10" type="primary" @click="onAdd">{{ $t('新增') }}</a-button> <a-popconfirm :title="$t('是否确认删除?')" :ok-text="$t('确定')" :cancel-text="$t('取消')" :visible="popconfirmVisible" @visibleChange="popconfirmVisibleChange" @confirm="onDeleteAll" > <a-button>{{ $t('删除') }}</a-button> </a-popconfirm> </div> </div> <div class="table-main-box"> <a-table :dataSource="tableData" :rowSelection="rowSelection" rowKey="id" :columns="columns" :pagination="false" size="small" > <template slot="meterCode" slot-scope="text, record, index"> <template v-if="text">{{ text }}</template> <template v-else> <a-select v-model="tableData[index].meterCode" :filterOption="filterOption" @change="value => changeMemterCode(value, index)" :placeholder="$t('请选择')" showSearch :allowClear="false" > <a-select-option v-for="item in disabledOptions" :key="item.id" :value="item.meterCode" :title="item.meterCode" :disabled="item.disabled" > {{ item.meterCode }} </a-select-option> </a-select> </template> </template> <template slot="action" slot-scope="text, record"> <a-popconfirm placement="topRight" :title="$t('是否确认删除?')" :ok-text="$t('确定')" :cancel-text="$t('取消')" @confirm="onDelete(record)" > <i class="ico-delete myIcon" :title="$t('删除')"></i> </a-popconfirm> </template> </a-table> </div> </a-form-model> </div> </template> </myModal> </div> </template> <script> import factory from '../factory'; import myModal from '@/components/scfComponents/modalComponents/modal.vue'; export default { components: { myModal }, data() { return { visible: false, formData: {}, rules: { taskName: [ { required: true, message: '请输入任务名称', trigger: 'blur' }, // { pattern: reg.name, message: this.$t('仅允许输入汉字、字母、数字与_-.@字符') }, ], }, columns: [ { title: this.$t('序号'), key: 'index', dataIndex: 'index', customRender: (text, record, index) => `${index + 1}`, }, { title: this.$t('子电表编号'), dataIndex: 'meterCode', key: 'meterCode', scopedSlots: { customRender: 'meterCode' }, }, { title: this.$t('操作'), key: 'action', width: 150, dataIndex: 'action', scopedSlots: { customRender: 'action' }, }, ], popconfirmVisible: false, meterOptions: [], selectedRowKeys: [], selectedRows: [], tableData: [], }; }, computed: { disabledOptions() { const usedCodes = this.tableData.map(item => item.meterCode).filter(code => code); return this.meterOptions.map(option => ({ ...option, disabled: usedCodes.includes(option.meterCode), })); }, rowSelection() { return { selectedRowKeys: this.selectedRowKeys, onChange: (selectedRowKeys, selectedRows) => { this.selectedRowKeys = selectedRowKeys; this.selectedRows = selectedRows; }, }; }, }, methods: { // 获取子电表列表 getChildMeterList(detectorCode) { let params = { detectorCodes: [detectorCode], page: 1, pageSize: 99999, }; factory.getChildMeterList(params).then(res => { if (res.success) { this.meterOptions = res.data.pageData || []; } }); }, showModal(record) { this.getChildMeterList(record.detectorCode); this.visible = true; }, filterOption(input, option) { return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0; }, changeMemterCode(value, index) { const selectedOption = this.meterOptions.find(el => el.meterCode === value); if (selectedOption) { this.$set(this.tableData, index, { ...this.tableData[index], detectorCode: selectedOption.detectorCode, meterCode: value, }); } // let checkOption = this.meterOptions.find(el => el.meterCode === value); // this.tableData.forEach(item => { // if (item.meterCode === checkOption.meterCode) { // item.detectorCode = checkOption.detectorCode; // } // }); // let selectedItems = this.tableData.map(item => item.meterCode).filter(el => el !== null && el !== ''); // this.meterOptions.forEach(el => { // if (selectedItems.includes(el.meterCode)) { // el.disabled = true; // } // }); }, // 批量删除提示框 popconfirmVisibleChange(visible) { if (visible && !this.selectedRowKeys.length) { this.popconfirmVisible = false; this.$message.destroy(); this.$message.warning(this.$t('请选择要删除的信息')); } else { this.popconfirmVisible = visible; } }, // 新增 onAdd() { let isNull = this.tableData.filter(e => e.meterCode === null || e.meterCode === ''); if (isNull.length) { this.$message.destroy(); return this.$message.warning(this.$t('请选择子电表编号')); } this.tableData.push({ id: Math.random().toString().split('.')[1], meterCode: null }); }, onDeleteAll() { if (this.selectedRows.length === 0) { this.$message.destroy(); return this.$message.warning(this.$t('请选择子电表')); } this.tableData = this.tableData.filter(item => !this.selectedRowKeys.includes(item.id)); // 清空选中状态 this.selectedRowKeys = []; this.selectedRows = []; // let codes = this.selectedRows.map(item => item.id); // this.tableData = this.tableData.filter(el => !codes.includes(el.id)); // let selectedItems = this.selectedRows.map(item => item.meterCode).filter(el => el !== null && el !== ''); // this.meterOptions.forEach(el => { // if (selectedItems.includes(el.meterCode)) { // el.disabled = false; // } // }); }, // 单个删除 onDelete(record) { this.tableData = this.tableData.filter(item => item.id !== record.id); // this.tableData = this.tableData.filter(item => item.id !== record.id); // if (record.meterCode) { // this.meterOptions.forEach(el => { // if (record.meterCode.indexOf(el.meterCode) !== -1) { // el.disabled = false; // } // }); // } }, submit() { this.visible = false; }, handleCancel() { this.visible = false; }, }, }; </script> <style lang="less" scoped> .edit-flow-meter-box { width: 100%; height: 100%; .table-title-box { width: 100%; display: flex; margin-bottom: 10px; align-items: center; justify-content: space-between; } } </style> 代码评审
最新发布
07-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值